首页 > 垃圾回收 > java面试题六:jvm内存结构及垃圾回收
2021
12-17

java面试题六:jvm内存结构及垃圾回收

  ( Java Virtual Machine Stacks)是线程私有的,生命周期与线程相同。虚拟机栈描述的是java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

  栈内存溢出最常见的错误就是StackOverflowError,程序有递归调用时候最容易发生

  方法区与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的是与ava堆区分开来。

  方法区在JDK1.7的时候叫做永久代,到JDK1.8之后废弃了永久代改为元空间(meta space);更新原因:1、字符串存在永久代中,容易出现性能问题和内存溢出。2、类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代(就小了)溢出。3、永久代会为 GC 带来不必要的复杂度,并且回收效率偏低

  Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块。堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存,Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。

  运行时常量池(Runtime Constant Pool)是方法区的一部分Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant Pool Table ),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。

  本地方法栈( Native Method Stack)与虚拟机栈所发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。

  程序计数器:当前线程所执行的字节码的行号指示器,用于记录正在执行的虚拟机字节指令地址,线程私有

  跟节点: 类加载器,thread, 虚拟机的本地变量表,static 成员,常量引用,本地方法栈的变量等

  标记清除:算法分为 “标记〞和“清除〞两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有。

  缺点:效率不高。标记和清除两个过程的效率都不高。产生碎片。碎片太多会导致提前GC。

  复制: 它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

  标记整理:标记过程仍然与 “标记-清除〞算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存

  并行( Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。适合科学计算、后台处理等弱交互场景

  并发(Concurrent):指用户线程与垃圾收集线程同时执行(但一定是并行的,可能会交替执行),垃圾收集线程在执行的时候不会停顿用户程序的运行。适合对响应时间有要求的场景,比如Web.

  RSet :记录了其他Region中的对象引用本Region中对象的关系,属于points-into结构(谁引用了我的对象)

  -xx:NewRatio等显式设置young区大小,会覆盖暂停时间目标。

  暂停时间目标 :暂停时间不要太严苛,其吞吐量目标是90%的应用程序时间和10%的垃圾回收时间,太严苛会直接影响到吞吐量

  如果吞吐量目标达不到,调大最大内存 ,不能让OS使用Swap,如果仍然达不到,降低目标。吞吐量能达到,GC时间太长,设置停顿时间的目标。


本文》有 0 条评论

留下一个回复