java面试题-JVM内存结构

news/2024/4/28 22:18:36/文章来源:https://blog.csdn.net/qq_33129875/article/details/129227567

整体结构:

1.说说JVM内存整体的结构?线程私有还是共享的?

JVM(Java Virtual Machine)内存可以分为以下几个部分:

  1. 程序计数器(Program Counter Register):是线程私有的,用于记录当前线程执行的字节码指令地址。

  1. Java虚拟机栈(JVM Stack):也是线程私有的,用于存储Java方法执行时的局部变量表、操作数栈、动态链接、方法出口等信息。

  1. 本地方法栈(Native Method Stack):与Java虚拟机栈类似,也是线程私有的,用于存储本地方法执行时的局部变量表、操作数栈等信息。

  1. Java堆(Java Heap):是所有线程共享的内存区域,用于存储Java对象实例和数组等数据。Java堆又可分为新生代和老年代两部分,其中新生代又可分为Eden空间、Survivor空间1和Survivor空间2。

  1. 方法区(Method Area):也是所有线程共享的内存区域,用于存储已加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

  1. 运行时常量池(Runtime Constant Pool):是方法区的一部分,用于存储编译期生成的各种字面量和符号引用,也是所有线程共享的。

  1. 直接内存(Direct Memory):不是JVM运行时数据区的一部分,但是JVM可以通过DirectByteBuffer类来操作直接内存。直接内存不受Java堆大小限制,可以使用本地系统内存。

总体来说,除了程序计数器、Java虚拟机栈和本地方法栈是线程私有的以外,其他内存区域都是所有线程共享的。

2.什么是程序计数器?

程序计数器(Program Counter Register)是JVM内存结构中的一部分,是线程私有的内存区域。它是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。当线程执行一个方法时,程序计数器记录的是正在执行的字节码的地址,当线程被切换回来时,它能够恢复到正确的执行位置。

在Java虚拟机中,每个线程都有自己的程序计数器,线程私有,所以它不会发生线程安全问题。当一个线程被创建时,它的程序计数器被初始化为0。在线程执行Java方法的时候,程序计数器会记录当前执行到哪个字节码指令。

程序计数器是一个非常小的内存区域,它是线程私有的,因此对于内存的使用并不是非常显著。但是,程序计数器在JVM的线程切换、异常处理、线程恢复等方面起着非常重要的作用。因此,程序计数器是JVM运行的必要组成部分,它的作用不容忽视。

3.什么是虚拟机栈

虚拟机栈(Java Virtual Machine Stack)是JVM内存结构中的一部分,是线程私有的内存区域,用于存储Java方法执行时的局部变量表、操作数栈、动态链接、方法出口等信息。

当一个线程开始执行一个方法时,JVM会为该方法创建一个栈帧(Stack Frame),并把栈帧压入该线程的虚拟机栈中。一个栈帧包含了一个方法的局部变量表、操作数栈、常量池指针等信息。

Java虚拟机栈的大小是在JVM启动时就可以预设的,每个线程的虚拟机栈大小可以通过JVM启动参数进行配置。如果一个线程的虚拟机栈空间不足以支持当前方法的执行,那么就会抛出StackOverflowError异常;如果JVM不能再为新的栈帧分配内存空间,就会抛出OutOfMemoryError异常。

虚拟机栈是线程私有的内存区域,因此,不同的线程有自己的虚拟机栈。这个特性保证了线程之间的内存隔离,一个线程的虚拟机栈不能被其他线程访问。虚拟机栈的线程私有性使得多线程之间的数据共享和通信需要通过一些协调机制来实现。虚拟机栈的线程私有性也意味着它的内存分配和回收操作是线程独立的,不会发生线程安全问题。

4.Java虚拟机栈如何进行方法计算的?

Java虚拟机栈是线程私有的内存区域,用于存储Java方法执行时的局部变量表、操作数栈、动态链接、方法出口等信息。当一个线程开始执行一个方法时,JVM会为该方法创建一个栈帧(Stack Frame),并把栈帧压入该线程的虚拟机栈中。一个栈帧包含了一个方法的局部变量表、操作数栈、常量池指针等信息。

当一个方法被调用时,JVM会将该方法的栈帧压入调用者线程的虚拟机栈中。执行该方法时,JVM会在该方法的栈帧中创建一个局部变量表,用于存储该方法的参数以及该方法中定义的局部变量。JVM还会在该栈帧中创建一个操作数栈,用于存储该方法中运算的操作数和中间结果。JVM通过操作数栈来进行方法的计算和运算。当方法返回时,JVM会弹出该方法的栈帧,将栈帧中的返回值传递给调用该方法的方法。

Java虚拟机栈通过栈帧来管理方法的调用和返回。在方法调用时,JVM会为该方法创建一个新的栈帧并压入调用者线程的虚拟机栈中;在方法返回时,JVM会弹出该方法的栈帧并返回结果。栈帧的创建和销毁是Java虚拟机栈的核心操作,因为它们涉及到方法的调用和返回,是程序运行的重要环节。

5.什么是本地方法栈

本地方法栈(Native Method Stack)是Java虚拟机栈的一部分,也是线程私有的内存区域,用于执行Native方法的。Native方法是指使用本地语言(如C、C++)编写的方法,可以被Java程序调用。与Java方法不同,Native方法的实现不在Java虚拟机中,而是在本地的操作系统和硬件平台上。

Java虚拟机通过本地方法栈来执行Native方法。当Java程序调用Native方法时,JVM会在本地方法栈中创建一个新的栈帧,并将Native方法的参数和返回值放在该栈帧中。Native方法的计算和运算都是在本地方法栈中进行的。当Native方法执行完毕时,JVM会将该方法的结果返回给Java程序,并弹出该方法的栈帧。

本地方法栈与虚拟机栈的功能类似,都是用于管理方法的调用和返回。但是,它们之间有一个重要的区别,即本地方法栈用于执行Native方法,而虚拟机栈用于执行Java方法。本地方法栈的大小也可以通过JVM启动参数进行配置。如果本地方法栈空间不足以支持当前Native方法的执行,就会抛出StackOverflowError异常;如果JVM不能再为新的栈帧分配内存空间,就会抛出OutOfMemoryError异常。

本地方法栈的线程私有性保证了不同线程之间的内存隔离,一个线程的本地方法栈不能被其他线程访问。本地方法栈的线程私有性还保证了它的内存分配和回收操作是线程独立的,不会发生线程安全问题。

6.什么是方法区

方法区(Method Area)是Java虚拟机中的一块内存区域,用于存储已经被加载的类的信息、常量、静态变量、即时编译器编译后的代码等数据。方法区是线程共享的内存区域,也是Java虚拟机中的永久代(Permanent Generation)。

方法区存储的是类级别的数据,与Java虚拟机栈和本地方法栈不同,它不是用于存储方法的局部变量和操作数栈等线程私有的数据。方法区的内存结构包含了运行时常量池、静态变量、类信息、即时编译器编译后的代码等内容。

运行时常量池是方法区的一部分,用于存储类和接口中的常量池信息。常量池中存储了常量、符号引用、字面量等数据,是Java程序中一些重要的静态数据结构。静态变量是指被static修饰的类变量,它们被存储在方法区中,它们的生命周期与类的生命周期一样长。

方法区还存储了类和接口的相关信息,包括类的访问修饰符、父类和接口信息、字段和方法信息等。这些信息在类加载的过程中被加载到方法区中,一旦被加载,就会一直存在于方法区中,直到虚拟机退出或被垃圾回收器回收。

另外,方法区还存储了即时编译器编译后的代码,即编译器优化后的本地代码。这些代码是存储在方法区中的,当某个方法被多次调用时,虚拟机会将该方法编译成本地代码,并存储在方法区中,以提高程序的执行效率。

方法区的大小可以通过JVM启动参数进行配置,如果方法区的空间不足以支持类的加载、常量池和代码的存储等操作,就会抛出OutOfMemoryError异常。方法区的线程共享性保证了所有线程都可以访问相同的类信息和静态变量,从而实现了内存的共享。

7.永久代和元空间内存使用上的差异?

永久代(Permanent Generation)和元空间(Metaspace)都是Java虚拟机中用于存储类元信息的内存区域。然而,它们在内存使用上有以下几点差异:

  1. 永久代是Java虚拟机规范中的一部分,而元空间是Java 8 引入的新特性,用于代替永久代。因此,永久代只在Java虚拟机中存在,而元空间则是Java虚拟机的一部分,可以使用操作系统的内存。

  1. 永久代的内存空间是固定的,在启动JVM时就已经分配了固定大小的内存,而元空间使用的是堆外内存,它的大小可以随着应用程序的需要进行动态调整。

  1. 永久代使用的内存是由JVM的堆内存分配的,而元空间使用的内存是由操作系统分配的。

  1. 永久代在Java虚拟机内存中的位置是在堆内存的末尾,而元空间位于堆外内存中。

  1. 永久代存储了类的元信息和静态变量等,而元空间存储了类的元信息和方法区信息,包括类名、类的父类、接口、字段、方法等。在元空间中,字符串常量池被存储在堆内存中。

  1. 永久代有可能会出现内存溢出的情况,例如常量池中存储的数据过多,导致永久代空间不足。而元空间不存在永久代的内存溢出问题,但如果元空间使用过度,会导致堆外内存溢出的问题。

总的来说,元空间比永久代更加灵活和可靠,可以根据应用程序的需要进行动态调整,避免了永久代的内存溢出问题。但是,由于元空间使用的是堆外内存,可能会增加操作系统的内存负担,需要注意内存使用的平衡和性能的优化。

8.堆区内存是怎么细分的?

Java虚拟机的堆区是Java应用程序中最大的内存区域,用于存储对象实例和数组等数据。堆区内存的细分主要有三个方面:新生代、老年代和永久代(在JDK8之前)/元空间(在JDK8及以后)。

  1. 新生代(Young Generation):年轻代是Java堆中的一部分,用于存储新创建的对象。年轻代被分为三个部分:一个Eden区和两个Survivor区(From和To),通常比例为Eden : Survivor = 8 : 1。新创建的对象首先会被分配到Eden区,当Eden区内存满时,就会触发一次Minor GC(年轻代垃圾回收),将Eden区和Survivor区中的存活对象复制到另一个Survivor区中,并清空Eden区和原Survivor区的内存。

  1. 老年代(Old Generation):老年代是Java堆中的一部分,用于存储存活时间较长的对象。在经过多次Minor GC后,仍然存活的对象就会被转移到老年代。当老年代内存满时,就会触发一次Major GC(老年代垃圾回收),清理老年代中的无用对象。老年代中的对象的生命周期比年轻代中的对象要长,垃圾回收的频率也比较低。

  1. 永久代(Perm Generation)/元空间(Metaspace):永久代或元空间是Java堆中的一部分,用于存储Java类的元数据,包括类名、方法名、常量池、字段描述等。永久代是在Java 7及之前的版本中使用的内存区域,而元空间是Java 8及之后的版本中使用的内存区域。永久代和元空间都是用来存储静态内容,与Java应用程序的堆内存无关。

堆内存的细分使得Java虚拟机可以更好地管理对象的内存使用,避免内存溢出等问题。

9.JVM中对象在堆中的生命周期?

在JVM中,对象在堆中的生命周期可以被描述为以下几个阶段:

  1. 创建对象:当使用new关键字创建一个新的对象时,JVM会在堆中分配一块内存来存储该对象。

  1. 使用对象:对象被创建后,程序可以对其进行操作,例如设置对象的属性值、调用对象的方法等。

  1. 对象不再被引用:当一个对象不再被任何引用变量所引用时,即没有任何方式可以访问到该对象时,JVM会将该对象标记为垃圾对象(Garbage Object)。

  1. 垃圾回收:当JVM需要更多的堆空间来分配新的对象时,会触发垃圾回收机制(Garbage Collection),该机制会扫描堆内存中所有的对象,并回收那些不再被引用的对象的内存空间。

  1. 对象被销毁:在垃圾回收机制释放了该对象的内存空间后,该对象就被销毁了,它所占用的内存空间也被回收。

需要注意的是,JVM中的垃圾回收机制是自动进行的,程序员无法直接控制。但是程序员可以通过优化代码,避免内存泄漏等问题,从而使得垃圾回收机制的效率更高,提高程序的性能和稳定性。

10.JVM中对象的分配过程?

在JVM中,对象的分配过程通常包括以下步骤:

  1. 检查堆空间是否有足够的内存来分配新的对象。如果没有足够的内存,则会触发垃圾回收机制来释放一些不再被引用的对象所占用的内存空间。

  1. 为对象分配内存。在JVM中,堆内存的分配通常是按照指针碰撞(Bump the Pointer)或空闲列表(Free List)的方式进行的。指针碰撞方式将内存分为已经分配的内存和未分配的内存两部分,用一个指针(指向下一个未分配的内存地址)将这两部分隔开;空闲列表方式将内存分为已经分配的内存和未分配的内存两部分,已经分配的内存被链表所连接,未分配的内存则是一个个独立的块。在分配内存时,JVM会在未分配的内存中找到一块足够大的内存块,并将其标记为已分配状态。

  1. 对象初始化。在为对象分配内存后,JVM会将分配到的内存空间清零,然后进行对象初始化,包括设置对象头信息、设置对象的默认值等。

  1. 返回对象引用。对象分配并初始化完成后,JVM会返回一个指向该对象的引用,这个引用可以用来访问对象的成员变量和方法等。

11.什么是 TLAB (Thread Local Allocation Buffer)?

TLAB(Thread Local Allocation Buffer)是为了优化Java虚拟机中的对象分配而引入的一种技术,它的存在主要是为了提高多线程程序中的对象分配性能。

在默认情况下,Java虚拟机中的对象分配是通过堆内存分配完成的。由于堆内存是所有线程共享的,多个线程可能会竞争同一块内存区域进行对象分配,从而导致性能下降。而使用TLAB技术后,每个线程都有自己的内存缓冲区,可以避免多个线程之间的竞争,提高对象分配的性能。

TLAB 分配过程

TLAB技术的优点包括:

1.减少了线程之间的竞争。每个线程都有自己的TLAB缓冲区,因此不同线程之间不会发生竞争,避免了锁竞争等问题,提高了对象分配的性能。

2.避免了内存碎片问题。由于每个线程都有自己的TLAB缓冲区,因此可以避免内存碎片问题,提高了内存的利用率。

3.提高了GC的效率。由于对象分配的缓冲区是线程私有的,因此可以使GC更加高效,减少了GC的暂停时间。

需要注意的是,使用TLAB技术也会带来一些额外的开销,例如每个线程都需要维护自己的缓冲区、缓冲区大小的调整等等。因此,在某些情况下,禁用TLAB技术可能会更好地适应特定的应用场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_74280.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入浅出解析ChatGPT引领的科技浪潮【AI行研商业价值分析】

Rocky Ding写在前面 【AI行研&商业价值分析】栏目专注于分享AI行业中最新热点/风口的思考与判断。也欢迎大家提出宝贵的意见或优化ideas,一起交流学习💪 大家好,我是Rocky。 2022年底,ChatGPT横空出世,火爆全网&a…

Linux学习(8.6)文件与目录的默认权限与隐藏权限

目录 文件与目录的默认权限与隐藏权限 文件的默认权限:umask chattr (配置文件隐藏属性) lsattr (显示文件隐藏属性) 文件特殊权限: SUID, SGID, SBIT 观察文件类型:file 以下内容转载自鸟哥的Linux私房菜 文件与目录的默认权限与隐藏权…

【架构师】零基础到精通——架构发展

博客昵称:架构师Cool 最喜欢的座右铭:一以贯之的努力,不得懈怠的人生。 作者简介:一名Coder,软件设计师/鸿蒙高级工程师认证,在备战高级架构师/系统分析师,欢迎关注小弟! 博主小留言…

【20230225】【剑指1】分治算法(中等)

1.重建二叉树class Solution { public:TreeNode* traversal(vector<int>& preorder,vector<int>& inorder){if(preorder.size()0) return NULL;int rootValuepreorder.front();TreeNode* rootnew TreeNode(rootValue);//int rootValuepreorder[0];if(preo…

redis秒杀

redis优惠券秒杀 为什么订单表订单ID不采用自增长&#xff1f; id规律性太明显&#xff0c;容易被用户猜测到&#xff08;比如第一天下订单id10&#xff0c;第二天下订单id100&#xff0c;在昨天的1天内只卖出90商品&#xff09;受单表数据量限制&#xff08;订单数据量大&am…

从零开始学习iftop流量监控(找出服务器耗费流量最多的ip和端口)

一、iftop是什么iftop是类似于top的实时流量监控工具。作用&#xff1a;监控网卡的实时流量&#xff08;可以指定网段&#xff09;、反向解析IP、显示端口信息等官网&#xff1a;http://www.ex-parrot.com/~pdw/iftop/二、界面说明>代表发送数据&#xff0c;< 代表接收数…

chatGPT模型原理

文章目录简介BertGPT 初代GPT-2GPT-3chatGPT开源ChatGPT简介 openai 的 GPT 大模型的发展历程。 Bert 2018年&#xff0c;自然语言处理 NLP 领域也步入了 LLM 时代&#xff0c;谷歌出品的 Bert 模型横空出世&#xff0c;碾压了以往的所有模型&#xff0c;直接在各种NLP的建模…

EasyRecovery16MAC苹果版本Photo最新版数据恢复软件

无论是在工作学习中&#xff0c;还是在生活中&#xff0c;Word、Excle等办公软件都是大家很常用的。我们在使用电脑的过程中&#xff0c;有时会因自己的误删或电脑故障&#xff0c;从而导致我们所写的文档丢失了。出现这样的大家不要着急&#xff0c;今天小编就给大家推荐一款可…

FreeRTOS优先级翻转

优先级翻转优先级翻转&#xff1a;高优先级的任务反而慢执行&#xff0c;低优先级的任务反而优先执行优先级翻转在抢占式内核中是非常常见的&#xff0c;但是在实时操作系统中是不允许出现优先级翻转的&#xff0c;因为优先级翻转会破坏任务的预期顺序&#xff0c;可能会导致未…

YOLOv5模型学习记录

新年伊始&#xff0c;YOLOv8横空出世&#xff0c;这个还未开源时便引发界内广泛热议的目标检测算法&#xff0c;一经问世便再次引发热潮&#xff0c;而作为与其师出同源的YOLOv5&#xff0c;自然要拿来与其比较一番。接下来我们便来学习一下吧。 模型结构 首先便是模型结构了…

Rasa 3.x 学习系列-摆脱意图:一种新的对话模式

Rasa 3.x 学习系列-摆脱意图:一种新的对话模式 在2019年的一篇文章中,Alan Nichol写道 :是时候摆脱意图了。一年后,Rasa发布了Rasa中的第一个无意图(或“端到端”)对话模型。现在,我们宣布迈出了一个重要的步伐,将LLM的强大功能带入Rasa的对话管理中。 首先,意图非常…

ACSC 2023 比赛复现

Admin Dashboard 在 index.php 中可以看到需要访问者是 admin 权限&#xff0c;才可以看到 flag。 report.php 中可以让 admin bot 访问我们输入的 url&#xff0c;那么也就是说可以访问 addadmin.php 添加用户。 在 addadmin.php 中可以添加 admin 用户&#xff0c;但是需…

李宏毅2023春季机器学习课程

目录2021&2022课程重磅须知我维护的其他项目更新日志课程地址课程资料直链课程作业直链其他优质课程2021&2022课程 CSDN Github 重磅须知 为方便所有网课资料与优质电子书籍的实时更新维护&#xff0c;创建一个在线实时网盘文件夹&#xff1b;   网盘获取方式&#…

mindspore的MLP模型(多层感知机)

导入模块 import hashlib import os import tarfile import zipfile import requests import numpy as np import pandas as pd import mindspore import mindspore.dataset as ds from mindspore import nn import mindspore.ops as ops import mindspore.numpy as mnp from …

Springdoc Swagger UI集成OAuth2认证

目录引言方式1&#xff1a;Bearer Token方式2&#xff1a;标准OAuth2授权码流程方式3&#xff1a;集成OIDC发现端点扩展&#xff1a;同时支持多种认证方式引言 之前的文章讲过OAuth2体系&#xff0c;以授权码流程为例&#xff08;参见下图&#xff09;&#xff0c; 其中资源服…

[SSD综述 1.3] SSD及固态存储技术半个世纪发展史

在我们今天看来&#xff0c;SSD已不再是个新鲜事物。这多亏了存储行业的前辈们却摸爬滚打了将近半个世纪&#xff0c;才有了SSD的繁荣&#xff0c; 可惜很多前辈都没有机会看到。所有重大的技术革新都是这样&#xff0c;需要长期的技术积累&#xff0c;一代一代的工程师们默默的…

基于springboot+vue的校园招聘系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

vue3+rust个人博客建站日记2-确定需求

反思 有人说过我们正在临近代码的终结点。很快&#xff0c;代码就会自动产生出来&#xff0c;不需要再人工编写。程序员完全没用了&#xff0c;因为商务人士可以从规约直接生成程序。 扯淡&#xff01;我们永远抛不掉代码&#xff0c;因为代码呈现了需求的细节。在某些层面上&a…

【Python从入门到进阶】9、流程控制语句-条件语句(if-else)

接上篇《8、Python的输入输出》 上一篇我们学习了Python的输入和输出相关内容。本篇我们来学习Python的控制流语句。 一、流程控制语句的含义 之前我们分别学习过“变量及数据类型”、“运算符”&#xff0c;其中“变量及数据类型”相当于我们学习自然语言中的“字”&#xf…

一文让你彻底理解Linux内核调度器进程优先级

一、前言 本文主要描述的是进程优先级这个概念。从用户空间来看&#xff0c;进程优先级就是nice value和scheduling priority&#xff0c;对应到内核&#xff0c;有静态优先级、realtime优先级、归一化优先级和动态优先级等概念。我们希望能在第二章将这些相关的概念描述清楚。…