JVM Code cache

When Java applications run, they are initially interpreted by the JVM. However, to improve performance, The JVM compiles frequently executed code segments into native machine code using the JIT compiler. This compiled code is then stored in the code cache.

code cache 一旦打满了 JIT 就会停,那这些 cache 什么时候回收以及更新呢?

在一定时间间隔内,如果 old 列表中方法没有被调用,这个方法就会被从 codeCache 充清除

在 JIT 被关闭之前,也就是 CodeCache 装满之前,会在 JIT 关闭前做一次清理,删除一些 CodeCache 的代码。

注意,Code Cache打满可导致应用性能降低-CSDN博客

JVM GC

它一般会在内存空闲或者内存占用过高的时候对那些没有任何引用的对象不定时地进行回收。

老年代、新生代和永久代

堆=新生代 + 老年代,不包括永久代(方法区)

年轻代用来存放新近创建的对象,年轻代的特点是对象更新速度快,在短时间内产生大量的“死亡对象”。

新生代分为 Eden 区域和 Survivor 区域,Survivor 区域由 FromSpace 和 ToSpace 组成。新建的对象都是由新生代分配内存,Eden 空间不足会把存货的对象转移到 Survivor 中。

新生代(Young Generation)是堆内存中的一个区域,用于存储新创建的对象。在 JVM 中的大多数对象都是短命的,会很快被创建并销毁。

老年代:用于存放新生代中经过多次垃圾回收仍然存活的对象。

永久代:指内存的永久保存区域,主要存放 Class 和 Meta(元数据)的信息,Class 在被加载的时候被放入永久区域。GC 不会在主程序运行期对永久区域进行清理。所以这也导致了永久代的区域会随着加载的 Class 的增多而胀满,最终抛出 OOM 异常。

G1 GC 新 GC

CMS GC 老 GC

CMS 仅仅作用于老年代?

Young GC / Minor GC

这两者是同一个东西

JVM 最核心的内存区域其实就是堆内存,会放各种我们创建出来的对象。 堆内存通常都会划分为新生代和老年代两个内存区域,对象一般来说都是优先放在新生代的。在年轻代(也可以叫做新生代)快要塞满的时候,就会触发年轻代 gc,也就是对年轻代进行垃圾回收,需要把年轻代里的垃圾对象都给回收掉。JVM 通过复制算法进行回收,通常来说新生代会有一块 Eden 区域用来创建对象,默认占据 80% 的内存,还有两块 Survivor 区域用来放垃圾回收后存活下来的对象,分别占据 10% 的内存。

而且大家要注意一点,一旦要对新生代进行垃圾回收了,此时一定会停止程序的运行,不让程序执行任何代码逻辑了,这个叫做“Stop the World” 此时只能允许后台的垃圾回收器的多个垃圾回收线程去工作,执行垃圾回收。

每次一旦年轻代塞满之后,进行垃圾回收时,这个期间都必须停止程序的运行!这个就是基于 JVM 运行的系统最害怕的问题:系统卡顿问题!

新生代内存的分配内存足够的话,通常来说系统可能在低峰时期在几个小时才有一次新生代 gc,高峰期最多也就几分钟一次新生代 gc。

Minor GC 采用复制算法。首先,把 Eden 和 SurvivorFrom 区域中存活的对象复制到 SurvivorTo 区域(如果有对象的年龄以及达到了老年的标准,则赋值到老年代区),同时把这些对象的年龄 +1(如果 SurvivorTo 不够位置了就放到老年区);然后,清空 Eden 和 SurvivorFrom 中的对象;最后,SurvivorTo 和 SurvivorFrom 互换,原 SurvivorTo 成为下一次 GC 时的 SurvivorFrom 区。

Major GC / Full GC

Major GC cleans up the old generation. Full GC is cleaning the entire Heap – both Young and Tenured spaces.

JVM 内存分布

Total - heap 就是非堆内存,还是在 JVM 里面的。

堆外内存就是把内存对象分配在 Java 虚拟机的堆以外的内存,这些内存直接受操作系统管理(而不是虚拟机),这样做的结果就是能够在一定程度上减少垃圾回收对应用程序造成的影响(因为这样就不受 JVM 管理,JVM 无法进行垃圾回收了,而是需要应用程序自己主动释放)。