1 gc
1.1 堆内存分布
jvm的内存中堆内存所占比例最大。内存回收主要是针对堆内存的,当然永久代(以前的名字)也会有gc。
堆内存分为年轻代和老年代,这两者在堆内存上的默认比例是1:2。也就是说年轻代大约占堆内存的1/3。
1.2 gc时机
minor gc的发生
full gc发生
1.3 gc算法
1.3.1 对象存活判断
首先GC主要是针对堆内存的gc。gc时机的确定是通过gc roots判断对象是否存活。
是否存活的判断是从gc roots沿着引用链 往下搜索,如果被引用。则是存活的。反之则非存活。
1.3.2 gc roots 说明
有四类可以作为roots。
其中虚拟机栈(栈帧中的本地变量表)中引用的对象作为roots是因为虚拟机栈代表这程序动态运行过程。
在过程中被引用肯定是不能被gc清理的。所以这中作为gc roots。
虚拟机栈(栈帧中的本地变量表)中引用的对象
1.3 gc日志分析
环境:jdk1.8 server模式
public class JvmTest {
private byte[] memory = new byte[8*1024*1024];
public static void main(String[] args) {
method01();
System.gc();
System.out.println("二次GC");
}
public static void method01() {
JvmTest t = new JvmTest();
System.gc();
System.out.println("一次GC");
}
}
[GC (System.gc()) [PSYoungGen: 2621K->496K(76288K)] 84541K->82424K(251392K), 0.0008198 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 496K->0K(76288K)] [ParOldGen: 81928K->82269K(175104K)] 82424K->82269K(251392K), [Metaspace: 2660K->2660K(1056768K)], 0.0065016 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
第一次GC完成
返回main方法
[GC (System.gc()) [PSYoungGen: 1310K->128K(76288K)] 83580K->82397K(251392K), 0.0015648 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
[Full GC (System.gc()) [PSYoungGen: 128K->0K(76288K)] [ParOldGen: 82269K->338K(175104K)] 82397K->338K(251392K), [Metaspace: 2662K->2662K(1056768K)], 0.0052017 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]
第二次GC完成
Heap
PSYoungGen total 76288K, used 2621K [0x000000076ab00000, 0x0000000770000000, 0x00000007c0000000)
eden space 65536K, 4% used [0x000000076ab00000,0x000000076ad8f750,0x000000076eb00000)
from space 10752K, 0% used [0x000000076f580000,0x000000076f580000,0x0000000770000000)
to space 10752K, 0% used [0x000000076eb00000,0x000000076eb00000,0x000000076f580000)
ParOldGen total 175104K, used 338K [0x00000006c0000000, 0x00000006cab00000, 0x000000076ab00000)
object space 175104K, 0% used [0x00000006c0000000,0x00000006c0054a88,0x00000006cab00000)
Metaspace used 2668K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 287K, capacity 386K, committed 512K, reserved 1048576K
注意:gc日志都很熟悉,但是指的一提的是图中标注“堆内存总量的地方”。网上对这个位置的数字的这个含义有两种说法。
有人说是堆内存使用总量,也有人说是Total available heap(即可以堆内存大小)。经过对上面数据的计算,证实的这个位置的确表示堆内存总量。