JVM

一、JAVA虚拟机区分:

  1. 堆内存:年轻代(eden(对象优先分配在此处)、存活区)、老年代;
  2. 非堆内存:持久代,存放方法、动态的变量/常量、线程栈

二、分区目的

  1. 为什么要分为年轻代和老年代?
    减少FGC的出现频率。
  2. 年轻代为什么要分为eden和存活区?
    减少垃圾回收到老年代的速度。

三、YGC和FGC

  1. YGC:只会在eden区满时触发YGC
    eden区满时,触发YGC(垃圾回收),这时JVM会判断eden中的对象是否还有引用指向它,没有引用的回收掉,有引用的挪到存活区。
    存活区:大小相等,位置互换。
    第二次YGC时会把还在引用的对象挪到S1,然后判断S0里的对象是否已经引用完。如果引用完,则回收掉;若未引用完,则从S0挪到S1.
  2. FGC触发条件
    • 老年代满了,会触发FullJC,这时触发FullJC是对整个堆内存(年轻代、老年代)和非堆内存(持久代)进行垃圾回收;
    • 持久代(非堆内存)满了也会触发fullgc;
    • 代码调用,人工执行system.gc runtime.cn 也会调用fullgc;
    • 执行了悲观策略(基于一些框架的时候会触发悲观策略),例如 jmap -dump
  3. FGC可以关闭手动调用。
    注:JVM调优时,尽量减少FGC的出现频率。因为FGC的时候会暂停线程引用,影响用户体验。YGC同

四、老年代

  1. 堆对象什么时候进入老年代?
    • 长期存活的进入老年代:触发15次YGC还存活的对象,进入老年代;
    • 大对象(存活区放不下)直接进入老年代。
  2. 老年代满了怎么办?
    • 如果多次FGC后,FGC残留把老年代空间占满了,这时只能重启服务。
    • 老年代满后会提示堆内存溢出。

你可能感兴趣的:(JVM)