先上代码:
生成单位大小对象的类:
public class GCDataObject {
byte[] bytes = null;
public GCDataObject(int i){
bytes = new byte[i *1024 * 1024];
}
}
测试逻辑:public class Test_MaxTenuringThreshold {
public static void main(String[] args){
//1-------------------------------------
GCDataObject old = new GCDataObject(9);
//清理掉新生代的16%内存到旧生代,不知道是什么。。。
System.gc();
<pre name="code" class="java">//2-------------------------------------
GCDataObject newObject1 = new GCDataObject(1);//为了填满旧生代,触发MinorGC使上面不可回收的对象进入Survivorfor(int ii = 0 ; ii < 5 ; ii++){new GCDataObject(1);}}} 注释掉2以下的代码并使用如下的参数运行一个虚拟机 ;
-Xmn10M -Xmx20M -Xms20M -verbose:gc -XX:+PrintGCDetails -XX:+UseSerialGC -XX:SurvivorRatio=3 -XX:MaxTenuringThreshold=1
[Full GC (System.gc()) [Tenured: 9216K->9738K(10240K), 0.0020278 secs] 10180K->9738K(18432K), [Metaspace: 2573K->2573K(1056768K)], 0.0020877 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
def new generation total 8192K, used 61K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
eden space 6144K, 1% used [0x00000000fec00000, 0x00000000fec0f738, 0x00000000ff200000)
from space 2048K, 0% used [0x00000000ff200000, 0x00000000ff200000, 0x00000000ff400000)
to space 2048K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff600000)
tenured generation total 10240K, used 9738K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
the space 10240K, 95% used [0x00000000ff600000, 0x00000000fff82b30, 0x00000000fff82c00, 0x0000000100000000)
Metaspace used 2580K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 286K, capacity 386K, committed 512K, reserved 1048576K
Heap
def new generation total 8192K, used 61K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
eden space 6144K, 1% used [0x00000000fec00000, 0x00000000fec0f738, 0x00000000ff200000)
from space 2048K, 0% used [0x00000000ff200000, 0x00000000ff200000, 0x00000000ff400000)
to space 2048K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff600000)
tenured generation total 10240K, used 9738K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
the space 10240K, 95% used [0x00000000ff600000, 0x00000000fff82b30, 0x00000000fff82c00, 0x0000000100000000)
Metaspace used 2580K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 286K, capacity 386K, committed 512K, reserved 1048576K
只触发了一次FullGC,是代码显式使用的System.gc触发,目的是为了让对象全部进入旧生代,如果有一个1M对象进入旧生代的话,就会触发FullGC,以此来判断设置新生代存活年龄的重要性。
取消注释,用和上面相同的参数运行一个jvm得到下面的日志:
[Full GC (System.gc()) [Tenured: 9216K->9738K(10240K), 0.0019239 secs] 10180K->9738K(18432K), [Metaspace: 2574K->2574K(1056768K)], 0.0019757 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [DefNew: 5242K->1024K(8192K), 0.0004939 secs] 14981K->10762K(18432K), 0.0005162 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
def new generation total 8192K, used 2109K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
eden space 6144K, 17% used [0x00000000fec00000, 0x00000000fed0f748, 0x00000000ff200000)
from space 2048K, 50% used [0x00000000ff400000, 0x00000000ff500030, 0x00000000ff600000)
to space 2048K, 0% used [0x00000000ff200000, 0x00000000ff200000, 0x00000000ff400000)
tenured generation total 10240K, used 9738K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
the space 10240K, 95% used [0x00000000ff600000, 0x00000000fff82b30, 0x00000000fff82c00, 0x0000000100000000)
Metaspace used 2581K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 286K, capacity 386K, committed 512K, reserved 1048576K
[GC (Allocation Failure) [DefNew: 5242K->1024K(8192K), 0.0004939 secs] 14981K->10762K(18432K), 0.0005162 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
def new generation total 8192K, used 2109K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
eden space 6144K, 17% used [0x00000000fec00000, 0x00000000fed0f748, 0x00000000ff200000)
from space 2048K, 50% used [0x00000000ff400000, 0x00000000ff500030, 0x00000000ff600000)
to space 2048K, 0% used [0x00000000ff200000, 0x00000000ff200000, 0x00000000ff400000)
tenured generation total 10240K, used 9738K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
the space 10240K, 95% used [0x00000000ff600000, 0x00000000fff82b30, 0x00000000fff82c00, 0x0000000100000000)
Metaspace used 2581K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 286K, capacity 386K, committed 512K, reserved 1048576K
可以看到from有一一半的空间(1M)被占用了,因为新对象存活年龄为1,所以发生了一次MinorGC后的那个1M的对象不仅进入旧生代。
再使用类似上面的参数,但是把-XX:MaxTenuringThreshold=0运行得到下面的日志:
[Full GC (System.gc()) [Tenured: 9216K->9738K(10240K), 0.0022147 secs] 10180K->9738K(18432K), [Metaspace: 2574K->2574K(1056768K)], 0.0022690 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [DefNew (promotion failed) : 5242K->5242K(8192K), 0.0002177 secs][Tenured: 9738K->9738K(10240K), 0.0016011 secs] 14981K->10762K(18432K), [Metaspace: 2574K->2574K(1056768K)], 0.0018564 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
def new generation total 8192K, used 2109K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
eden space 6144K, 34% used [0x00000000fec00000, 0x00000000fee0f758, 0x00000000ff200000)
from space 2048K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff600000)
to space 2048K, 0% used [0x00000000ff200000, 0x00000000ff200000, 0x00000000ff400000)
tenured generation total 10240K, used 9738K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
the space 10240K, 95% used [0x00000000ff600000, 0x00000000fff82b50, 0x00000000fff82c00, 0x0000000100000000)
Metaspace used 2580K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 286K, capacity 386K, committed 512K, reserved 1048576K
[GC (Allocation Failure) [DefNew (promotion failed) : 5242K->5242K(8192K), 0.0002177 secs][Tenured: 9738K->9738K(10240K), 0.0016011 secs] 14981K->10762K(18432K), [Metaspace: 2574K->2574K(1056768K)], 0.0018564 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
def new generation total 8192K, used 2109K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
eden space 6144K, 34% used [0x00000000fec00000, 0x00000000fee0f758, 0x00000000ff200000)
from space 2048K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff600000)
to space 2048K, 0% used [0x00000000ff200000, 0x00000000ff200000, 0x00000000ff400000)
tenured generation total 10240K, used 9738K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
the space 10240K, 95% used [0x00000000ff600000, 0x00000000fff82b50, 0x00000000fff82c00, 0x0000000100000000)
Metaspace used 2580K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 286K, capacity 386K, committed 512K, reserved 1048576K
可见那个1M的不可回收的对象立马进入旧生代,导致旧生代触发FullGC。旧生代放不下,放在了Eden下。Eden为2M。
注意这个值只有在串行gc和并行gc的时候才可以用