当前位置:   article > 正文

JVM之回收策略的详细解析

JVM之回收策略的详细解析

回收策略

触发条件

内存垃圾回收机制主要集中的区域就是线程共享区域:堆和方法区

Minor GC 触发条件非常简单,当 Eden 空间满时,就将触发一次 Minor GC

FullGC 同时回收新生代、老年代和方法区,只会存在一个 FullGC 的线程进行执行,其他的线程全部会被挂起,有以下触发条件:

  • 调用 System.gc():

    • 在默认情况下,通过 System.gc() 或 Runtime.getRuntime().gc() 的调用,会显式触发 FullGC,同时对老年代和新生代进行回收,但是虚拟机不一定真正去执行,无法保证对垃圾收集器的调用

    • 不建议使用这种方式,应该让虚拟机管理内存。一般情况下,垃圾回收应该是自动进行的,无须手动触发;在一些特殊情况下,如正在编写一个性能基准,可以在运行之间调用 System.gc()

  • 老年代空间不足:

    • 为了避免引起的 Full GC,应当尽量不要创建过大的对象以及数组

    • 通过 -Xmn 参数调整新生代的大小,让对象尽量在新生代被回收掉不进入老年代,可以通过 -XX:MaxTenuringThreshold 调大对象进入老年代的年龄,让对象在新生代多存活一段时间

  • 空间分配担保失败

  • JDK 1.7 及以前的永久代(方法区)空间不足

  • Concurrent Mode Failure:执行 CMS GC 的过程中同时有对象要放入老年代,而此时老年代空间不足(可能是 GC 过程中浮动垃圾过多导致暂时性的空间不足),便会报 Concurrent Mode Failure 错误,并触发 Full GC

手动 GC 测试,VM参数:-XX:+PrintGcDetails

  1. public void localvarGC1() {
  2.    byte[] buffer = new byte[10 * 1024 * 1024];//10MB
  3.    System.gc(); //输出: 不会被回收, FullGC时被放入老年代
  4. }
  5. public void localvarGC2() {
  6.    byte[] buffer = new byte[10 * 1024 * 1024];
  7.    buffer = null;
  8.    System.gc(); //输出: 正常被回收
  9. }
  10. public void localvarGC3() {
  11.     {
  12.         byte[] buffer = new byte[10 * 1024 * 1024];
  13.     }
  14.     System.gc(); //输出: 不会被回收, FullGC时被放入老年代
  15. }
  16. public void localvarGC4() {
  17.   {
  18.        byte[] buffer = new byte[10 * 1024 * 1024];
  19.   }
  20.    int value = 10;
  21.    System.gc(); //输出: 正常被回收,slot复用,局部变量过了其作用域 buffer置空
  22. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/625788
推荐阅读
相关标签
  

闽ICP备14008679号