Java垃圾回收

java运行时内存区

(1)线程私有区:

  • 程序计数器,记录正在执行的虚拟机字节码的地址;
  • 虚拟机栈:方法执行的内存区,每个方法执行时会在虚拟机栈中创建栈帧;
  • 本地方法栈:虚拟机的Native方法执行的内存区;

(2)线程共享区:

  • Java堆:对象分配内存的区域,这是垃圾回收的主战场;
  • 方法区:存放类信息、常量、静态变量、编译器编译后的代码等数据,另外还有一个常量池。当然垃圾回收也会在这个区域工作。

什么时候

说明minor gc/full gc的触发条件、OOM的触发条件,降低GC的调优的策略。
①大多数情况下,对象在新生代的Eden区分配,如果没有足够空间,则虚拟机将发起一次Minor GC(Minor GC发生在新生代的垃圾回收)
②Full GC的触发条件:

  • 老年代代空间不足
  • 方法区空间不足时(HotSpot的永久区)
  • 统计得到的Minor GC晋升到老年代的平均大小大于老年代的剩余空间。
    例如程序第一次触发Minor GC后,有6MB的对象晋升到旧生代,那么当下一次Minor GC发生时,首先检查旧生代的剩余空间是否大于6MB,如果小于6MB,
    则执行Full GC。
  • 堆中分配很大的对象,需要大量连续内存空间的java对象,此种对象会直接进入老年代,而老年代虽然有很大的剩余空间,但是无法找到足够大的连续空间来分配给当前对象,此种情况就会触发JVM进行Full GC。
  • System.gc()方法的调用:比较少用

eden满了minor gc,升到老年代的对象大于老年代剩余空间full gc,

或者小于时被HandlePromotionFailure参数强制full gc;gc与非gc时间耗时超过了GCTimeRatio的限制引发OOM,调优诸如通过NewRatio控制新生代老年代比例,通过MaxTenuringThreshold控制进入老年前生存次数等

对什么东西

从gc roots搜索不到,而且经过第一次标记、清理后,仍然没有复活的对象。

做什么事情

能说出诸如新生代做的是复制清理、from survivor、to survivor是干啥用的、老年代做的是标记清理、标记清理后碎片要不要整理、复制清理和标记清理有有什么优劣势等。

还能讲清楚串行、并行(整理/不整理碎片)、CMS等搜集器可作用的年代、特点、优劣势,并且能说明控制/调整收集器选择的方式。

可达性算法

这是目前主流的虚拟机都是采用GC Roots Tracing算法
可以作为GC Roots的对象(见下图):

  • 虚拟机栈的栈帧的局部变量表所引用的对象;
  • 本地方法栈的JNI(Java Native Interface)所引用的对象;
  • 方法区的静态变量和常量所引用的对象;
    image

参考资料:

  1. 作者:郭无心
    链接:https://www.zhihu.com/question/35164211/answer/68265045
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  2. 作者:Gityuan
    链接:https://www.zhihu.com/question/21539353
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  3. 深入理解JVM虚拟机. https://book.douban.com/subject/24722612/

posted @ 2017-04-14 21:14  cswxa  阅读(206)  评论(0编辑  收藏  举报