JVM垃圾回收内部详解

Posted jiangzhongwei_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM垃圾回收内部详解相关的知识,希望对你有一定的参考价值。

一. 内存结构       

JVM运行时内存主要划分为五个区域:方法区、java栈、本地方法栈、java堆、程序计数器。

  

    方法区主要存放编译后的class类信息、常量、静态变量等

    java栈分为虚拟机栈和本地方法栈。虚拟机栈存放java运行线程的方法栈帧、局部变量等;而本地方法栈存放引用

的native方法服务信息。

    java堆存放运行时分配的对象实例,由新生代(包括eden区、s1区、s2区)和老年代组成

    程序计数器是线程执行时的指针,每执行一步 指针就指向下一个指令代码,每个线程都有一个私有的程序计数器

二 . 垃圾回收

    垃圾回收有MinorGC(又称YoungGC)和FullGC, 前者为新生代的垃圾回收,后者为老年代垃圾回收

     2.1 MinorGC

     新生代内存默认比例为eden:s1:s2 = 8:1:1

      

      MinorGC采用的是复制清除算法:

      首先内存中的新生对象会直接分配到eden区,当eden区无法为对象实例分配内存时(a),触发第一次MinorGC,此时会标记eden内的存活对象,并将其转移到s1区,然后jvm垃圾回收线程将eden区垃圾清除,此时eden区为空,s1存放存活对象;

      当eden区再次堆满时,会进行第二次MinorGC, 这时JVM标记eden区存活对象,并将其和s1的存活对象一起复制到s2区(b),进行垃圾清除后,eden区为空,s1区为空,s2存放两次累计的存活对象

    当eden区第三次满时,同理将eden区标记的存活对象和s2区的对象一起转移到s1...如此周而复始,等到s1或者s2容纳不下复制过来的存活对象时,jvm就会直接将这些对象放到老年区。当然

            1.  经过15次MinorGC后仍然没有被回收的对象也会放入老年区,

            2.  当 年龄1存活对象 + 年龄2存活对象 + .. +年龄n存活对象 >= s1或者s2区内存大小的一半,该区内所有年龄大于n的存活对象都直接进入老年代,也叫动态对象年龄判断

      当老年区也放不下对象时,触发FullGC.

      以上是一般情况下的MinorGC,不一般的情况呢?

      场景a. 这里会进行一次内存检查:比较老年区可用内存和新生代所有对象内存大小,如果前者比后者小,那么会直接进行一次FullGC,为啥?主要是防止新生代对象都存活下来,直接转移到老年代里了,这里提取预防下

      场景b. s区放不下这些存活对象了,要放到老年区里,但是这会儿老年区也放不下,也会触发FullGC

三.  垃圾回收器

     垃圾回收器根据新生代和老年代来划分的,比如新生代的垃圾回收器有ParaNew、serial、cms、g1等。

    未完待续

以上是关于JVM垃圾回收内部详解的主要内容,如果未能解决你的问题,请参考以下文章

JVM垃圾回收内部详解

搞定 JVM 垃圾回收就是这么简单

Java垃圾回收机制(GC)详解

JVM--17---垃圾回收相关概念

(超详解)JVM-垃圾回收

详解JVM 的垃圾回收算法和垃圾回收器