JVM-GC

2018-01-29  本文已影响17人  01010100

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5.4

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.4

运行时数据区

The pc Register

Java Virtual Machine Stacks

Heap

Method Area

Run-Time Constant Pool

Native Method Stacks

一次运行:

public class JustTest {

public static MapSTATIC = new HashMap();

public static void main(String[] args) {

for(int i=0; i< Integer.MAX_VALUE; i++) {

try {

String key =  i + "_" +UUID.randomUUID().toString();

String value =  UUID.randomUUID().toString();

STATIC.put(key, value);

Thread.sleep(1L);

System.out.println(key +  " ====== " + " " + value);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

参数:

-Xms32m

-Xmx256m

结果:

区域 初始值 最大值  

Eden 8.5 68.312  

S0 1.062 8.5  

S1 1.062 8.5  

Old 21.375 170.688  

Perm 20.750 82

Young = Eden + Survivor(S0 + S1) = 10.624

Old = Old = 21.375

Heap = Young + Old =32M

其中,大概可以看出默认比例:Eden:S0:S1 = 8:1:1,Young : Old = 1 : 2

可以通过 -XX:SurvivorRatio=8 -> Eden : S0/S1 = 8:1, -XX:NewRatio=2 -> Old : Young(New)=2 ,

从这里也可以看出,Perm(永久代)不属于Heap

再提一下永久代和方法区的概念,方法区是一个逻辑概念。而Hotspot虚拟机是通过Perm Gen来实现的,并且Perm Gen是Hotspot特有的概念,并且在jdk 8中已经移除。

从下图中可以看出,内存分配和GC的一些过程:

详细过程见:GC Detail

详细的前二次GC:

1、初始内存分配到Eden

  此时,S0、S1、Old 内存都为0

2、Eden空间逐渐占满,触发GC1,回收之后将Eden中存活的对象复制到S1,S1存放不下的,则进入Old。

  此时,S1 1.062全部使用,还有583.133K 进入Old

3、GC1之后,Enden被清空,内存依旧分配到Enden,至Enden再次占满

4、触发GC2,将Eden和S1中还存活的对象复制到S0,其他存放不下的对象直接进入Old

  此时,S0 958.218K,Old 1.672M,相比上次,又新进入了一些对象

5、重复

注意:内存直接分配到Eden,而不会直接分配到Survivor(SO/S1)。

      当Eden占满时,将存活的对象复制到其中一个空的Survivor区域。

GC调优案例:

https://tech.meituan.com/jvm_optimize.html

http://blogxin.cn/2015/12/02/FullGC-frequently/

上一篇 下一篇

猜你喜欢

热点阅读