-Xmx64M -Xms64M -XX:+PrintGCDetails
package com.mousycoder.mycode.thinking_in_jvm; /** * @version 1.0 * @author: mousycoder * @date: 2019-07-15 18:06 */ public class AllocEden { public static final int _1K = 1024; public static void main(String[] args) { for (int i = 0; i < 5 * _1K; i++) { byte[] b = new byte[_1K]; } } }
输出
Heap PSYoungGen total 18944K, used 7250K [0x00000007beb00000, 0x00000007c0000000, 0x00000007c0000000) eden space 16384K, 44% used [0x00000007beb00000,0x00000007bf214968,0x00000007bfb00000) from space 2560K, 0% used [0x00000007bfd80000,0x00000007bfd80000,0x00000007c0000000) to space 2560K, 0% used [0x00000007bfb00000,0x00000007bfb00000,0x00000007bfd80000) ParOldGen total 44032K, used 0K [0x00000007bc000000, 0x00000007beb00000, 0x00000007beb00000) object space 44032K, 0% used [0x00000007bc000000,0x00000007bc000000,0x00000007beb00000) Metaspace used 2741K, capacity 4486K, committed 4864K, reserved 1056768K class space used 297K, capacity 386K, committed 512K, reserved 1048576K
没有 GC 发生,分配的 5M 对象都在 Eden 区
-Xmx1024M -Xms1024M -XX:+PrintGCDetails -XX:MaxTenuringThreshold=10 -XX:+PrintHeapAtGC
package com.mousycoder.mycode.thinking_in_jvm; import java.util.HashMap; import java.util.Map; /** * @version 1.0 * @author: mousycoder * @date: 2019-07-16 10:05 */ public class MaxTenuringThreshold { public static final int _1M = 1024 * 1024; public static final int _1K = 1024; public static void main(String[] args) { Map<Integer,byte[]> map = new HashMap<>(); for (int i = 0; i < 5 * _1K; i++) { byte[] b = new byte[_1K]; map.put(i,b); } for (int i = 0; i < 17; i++) { for (int j = 0; j < 270; j++) { byte[] g = new byte[_1M]; } } } }
输出
{Heap before GC invocations=1 (full 0): PSYoungGen total 305664K, used 261739K [0x00000007aab00000, 0x00000007c0000000, 0x00000007c0000000) eden space 262144K, 99% used [0x00000007aab00000,0x00000007baa9acc0,0x00000007bab00000) from space 43520K, 0% used [0x00000007bd580000,0x00000007bd580000,0x00000007c0000000) to space 43520K, 0% used [0x00000007bab00000,0x00000007bab00000,0x00000007bd580000) ParOldGen total 699392K, used 0K [0x0000000780000000, 0x00000007aab00000, 0x00000007aab00000) object space 699392K, 0% used [0x0000000780000000,0x0000000780000000,0x00000007aab00000) Metaspace used 2737K, capacity 4486K, committed 4864K, reserved 1056768K class space used 296K, capacity 386K, committed 512K, reserved 1048576K [GC (Allocation Failure) [PSYoungGen: 261739K->6128K(305664K)] 261739K->6136K(1005056K), 0.0044940 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] Heap after GC invocations=1 (full 0): PSYoungGen total 305664K, used 6128K [0x00000007aab00000, 0x00000007c0000000, 0x00000007c0000000) eden space 262144K, 0% used [0x00000007aab00000,0x00000007aab00000,0x00000007bab00000) from space 43520K, 14% used [0x00000007bab00000,0x00000007bb0fc020,0x00000007bd580000) to space 43520K, 0% used [0x00000007bd580000,0x00000007bd580000,0x00000007c0000000) ParOldGen total 699392K, used 8K [0x0000000780000000, 0x00000007aab00000, 0x00000007aab00000) object space 699392K, 0% used [0x0000000780000000,0x0000000780002000,0x00000007aab00000) Metaspace used 2737K, capacity 4486K, committed 4864K, reserved 1056768K class space used 296K, capacity 386K, committed 512K, reserved 1048576K } ` ` ` {Heap before GC invocations=11 (full 0): PSYoungGen total 339456K, used 330101K [0x00000007aab00000, 0x00000007c0000000, 0x00000007c0000000) eden space 330752K, 99% used [0x00000007aab00000,0x00000007bed15410,0x00000007bee00000) from space 8704K, 3% used [0x00000007bf780000,0x00000007bf7c8000,0x00000007c0000000) to space 9216K, 0% used [0x00000007bee00000,0x00000007bee00000,0x00000007bf700000) ParOldGen total 699392K, used 6401K [0x0000000780000000, 0x00000007aab00000, 0x00000007aab00000) object space 699392K, 0% used [0x0000000780000000,0x0000000780640468,0x00000007aab00000) Metaspace used 3065K, capacity 4486K, committed 4864K, reserved 1056768K class space used 341K, capacity 386K, committed 512K, reserved 1048576K [GC (Allocation Failure) [PSYoungGen: 330101K->0K(339968K)] 336502K->6613K(1039360K), 0.0005330 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Heap after GC invocations=11 (full 0): PSYoungGen total 339968K, used 0K [0x00000007aab00000, 0x00000007c0000000, 0x00000007c0000000) eden space 330752K, 0% used [0x00000007aab00000,0x00000007aab00000,0x00000007bee00000) from space 9216K, 0% used [0x00000007bee00000,0x00000007bee00000,0x00000007bf700000) to space 9216K, 0% used [0x00000007bf700000,0x00000007bf700000,0x00000007c0000000) ParOldGen total 699392K, used 6613K [0x0000000780000000, 0x00000007aab00000, 0x00000007aab00000) object space 699392K, 0% used [0x0000000780000000,0x0000000780675478,0x00000007aab00000) Metaspace used 3065K, capacity 4486K, committed 4864K, reserved 1056768K class space used 341K, capacity 386K, committed 512K, reserved 1048576K } ` ` ` {Heap before GC invocations=15 (full 0): PSYoungGen total 339968K, used 329747K [0x00000007aab00000, 0x00000007c0000000, 0x00000007c0000000) eden space 330752K, 99% used [0x00000007aab00000,0x00000007bed04fb8,0x00000007bee00000) from space 9216K, 0% used [0x00000007bf700000,0x00000007bf700000,0x00000007c0000000) to space 9216K, 0% used [0x00000007bee00000,0x00000007bee00000,0x00000007bf700000) ParOldGen total 699392K, used 6613K [0x0000000780000000, 0x00000007aab00000, 0x00000007aab00000) object space 699392K, 0% used [0x0000000780000000,0x0000000780675478,0x00000007aab00000) Metaspace used 3065K, capacity 4486K, committed 4864K, reserved 1056768K class space used 341K, capacity 386K, committed 512K, reserved 1048576K [GC (Allocation Failure) [PSYoungGen: 329747K->0K(339968K)] 336361K->6613K(1039360K), 0.0003440 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] Heap after GC invocations=15 (full 0): PSYoungGen total 339968K, used 0K [0x00000007aab00000, 0x00000007c0000000, 0x00000007c0000000) eden space 330752K, 0% used [0x00000007aab00000,0x00000007aab00000,0x00000007bee00000) from space 9216K, 0% used [0x00000007bee00000,0x00000007bee00000,0x00000007bf700000) to space 8704K, 0% used [0x00000007bf780000,0x00000007bf780000,0x00000007c0000000) ParOldGen total 699392K, used 6613K [0x0000000780000000, 0x00000007aab00000, 0x00000007aab00000) object space 699392K, 0% used [0x0000000780000000,0x0000000780675478,0x00000007aab00000) Metaspace used 3065K, capacity 4486K, committed 4864K, reserved 1056768K class space used 341K, capacity 386K, committed 512K, reserved 1048576K }
其实第 11 次的时候,新生代的 5M 对象已经晋级到老年代了,MaxTenuringThreshold 为充分非必要条件(达到次数一定晋升,没达到可能也晋升)
如果
-Xmx1024M -Xms1024M -XX:+PrintGCDetails -XX:MaxTenuringThreshold=10 -XX:+PrintHeapAtGC -XX:TargetSurvivorRatio=13
输出
{Heap before GC invocations=7 (full 0): PSYoungGen total 343040K, used 342362K [0x00000007aab00000, 0x00000007c0000000, 0x00000007c0000000) eden space 336896K, 99% used [0x00000007aab00000,0x00000007bf36e968,0x00000007bf400000) from space 6144K, 98% used [0x00000007bfa00000,0x00000007bffe8010,0x00000007c0000000) to space 6144K, 0% used [0x00000007bf400000,0x00000007bf400000,0x00000007bfa00000) ParOldGen total 699392K, used 8K [0x0000000780000000, 0x00000007aab00000, 0x00000007aab00000) object space 699392K, 0% used [0x0000000780000000,0x0000000780002000,0x00000007aab00000) Metaspace used 2740K, capacity 4486K, committed 4864K, reserved 1056768K class space used 296K, capacity 386K, committed 512K, reserved 1048576K [GC (Allocation Failure) [PSYoungGen: 342362K->0K(337408K)] 342370K->6397K(1036800K), 0.0042910 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] Heap after GC invocations=7 (full 0): PSYoungGen total 337408K, used 0K [0x00000007aab00000, 0x00000007c0000000, 0x00000007c0000000) eden space 336896K, 0% used [0x00000007aab00000,0x00000007aab00000,0x00000007bf400000) from space 512K, 0% used [0x00000007bf400000,0x00000007bf400000,0x00000007bf480000) to space 7680K, 0% used [0x00000007bf880000,0x00000007bf880000,0x00000007c0000000) ParOldGen total 699392K, used 6397K [0x0000000780000000, 0x00000007aab00000, 0x00000007aab00000) object space 699392K, 0% used [0x0000000780000000,0x000000078063f458,0x00000007aab00000) Metaspace used 2740K, capacity 4486K, committed 4864K, reserved 1056768K class space used 296K, capacity 386K, committed 512K, reserved 1048576K }
则第 7 次 GC 的时候,已经晋升到老年代了 (TargetSurvivorRatio=13 代表 S 区使用率超过 13%后,马上使用较小的 age 晋升到老年代)
-Xmx32m -Xms32m -XX:+UseSerialGC -XX:+PrintGCDetails -XX:PretenureSizeThreshold=1000 -XX:-UseTLAB
-XX:-UseTLAB 禁用 TLAB -XX:PretenureSizeThreshold=1000 超过 1000 字节的对象直接分配到老年代
package com.mousycoder.mycode.thinking_in_jvm; import java.util.HashMap; import java.util.Map; /** * @version 1.0 * @author: mousycoder * @date: 2019-07-16 11:04 */ public class PretenureSizeThreshold { public static final int _1K = 1024; public static void main(String[] args) { Map<Integer,byte[]> map = new HashMap<>(); for (int i = 0; i < 5 * _1K; i++) { byte[] b = new byte[_1K]; map.put(i,b); } } }
输出
Heap def new generation total 9792K, used 924K [0x00000007be000000, 0x00000007beaa0000, 0x00000007beaa0000) eden space 8704K, 10% used [0x00000007be000000, 0x00000007be0e72e8, 0x00000007be880000) from space 1088K, 0% used [0x00000007be880000, 0x00000007be880000, 0x00000007be990000) to space 1088K, 0% used [0x00000007be990000, 0x00000007be990000, 0x00000007beaa0000) tenured generation total 21888K, used 5430K [0x00000007beaa0000, 0x00000007c0000000, 0x00000007c0000000) the space 21888K, 24% used [0x00000007beaa0000, 0x00000007befed868, 0x00000007befeda00, 0x00000007c0000000) Metaspace used 2743K, capacity 4486K, committed 4864K, reserved 1056768K class space used 297K, capacity 386K, committed 512K, reserved 1048576K
可见直接分配到老年代了
TLAB 是Thread Local Allocation Buffer 线程本地分配缓存,为了加速对象分配,避免堆共享同步
package com.mousycoder.mycode.thinking_in_jvm; /** * @version 1.0 * @author: mousycoder * @date: 2019-07-16 11:23 */ public class UseTLAB { public static void alloc(){ byte[] b = new byte[2]; b[0] = 1; } public static void main(String[] args) { long b = System.currentTimeMillis(); for (int i = 0; i < 10000000; i++) { alloc(); } long e = System.currentTimeMillis(); System.out.println(e -b ); } }
开启 TLAB ,启用函数 JIT,禁止逃逸分析和后台编译
-XX:+UseTLAB -Xcomp -XX:-BackgroundCompilation -XX:-DoEscapeAnalysis -server
输出
关闭 TLAB
-XX:-UseTLAB -Xcomp -XX:-BackgroundCompilation -XX:-DoEscapeAnalysis -server
输出
可见 TLAB 可以加速对象分配
注意:
TLAB 一般空间不会太大,很容易装满,如果一个 100KB 的空间,已经使用了 80KB,当需要再分配一个 30KB 的对象时,虚拟机有 2 种选择,第一:废弃当前 TLAB,浪费 20KB 空间;第二:将 30KB 对象直接分配到堆上,保留当前 TLAB,将来有小于 20KB 的对象直接使用此块空间。虚拟机根据 refill_waste的值,当请求对象大于 refill_waste,会在堆中分配,小于则废弃 当前TLAB,新建 TLAB 分配新对象,这个阈值由 TLABRefillWasteFraction调整,默认值是 64,代表 1/64的 TLAB 空间作为 refill_waste
开启 TLAB 跟踪详情(-XX:+PrintTLAB)
-XX:+UseTLAB -server -XX:+PrintTLAB -XX:+PrintGC -XX:TLABSize=102400 -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=100 -XX:-DoEscapeAnalysis
-XX:TLABSize 代表分配 TLAB 大小,
输出
TLAB: gc thread: 0x00007f943804c800 [id: 11523] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 9.76562 5000KB refills: 1 waste 98.9% gc: 101296B slow: 0B fast: 0B TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 9.76562 5000KB refills: 5 waste 0.1% gc: 0B slow: 488B fast: 0B TLAB totals: thrds: 2 refills: 6 max: 5 slow allocs: 0 max 0 waste: 16.6% gc: 101296B max: 101296B slow: 488B max: 488B fast: 0B max: 0B [GC (Allocation Failure) 512K->352K(130560K), 0.0012200 secs] TLAB: gc thread: 0x00007f9438034000 [id: 18179] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 9.76562 5000KB refills: 1 waste 99.7% gc: 102080B slow: 0B fast: 0B TLAB: gc thread: 0x00007f9438046800 [id: 20483] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 9.76562 5000KB refills: 1 waste 100.0% gc: 102384B slow: 0B fast: 0B TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 5.37109 2750KB refills: 4 waste 0.0% gc: 0B slow: 120B fast: 0B TLAB totals: thrds: 3 refills: 6 max: 4 slow allocs: 0 max 0 waste: 33.3% gc: 204464B max: 102384B slow: 120B max: 120B fast: 0B max: 0B [GC (Allocation Failure) 864K->528K(131072K), 0.0007710 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 3.76465 3855KB refills: 13 waste 0.0% gc: 0B slow: 72B fast: 16B TLAB totals: thrds: 1 refills: 13 max: 13 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 72B max: 72B fast: 16B max: 16B [GC (Allocation Failure) 1552K->544K(131072K), 0.0006530 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 2.89136 2961KB refills: 13 waste 0.0% gc: 0B slow: 40B fast: 8B TLAB totals: thrds: 1 refills: 13 max: 13 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 40B max: 40B fast: 8B max: 8B [GC (Allocation Failure) 1568K->560K(132096K), 0.0006120 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 2.32372 4759KB refills: 23 waste 0.0% gc: 0B slow: 40B fast: 8B TLAB totals: thrds: 1 refills: 23 max: 23 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 40B max: 40B fast: 8B max: 8B [GC (Allocation Failure) 2608K->584K(132096K), 0.0005550 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 1.90348 3898KB refills: 21 waste 0.0% gc: 0B slow: 40B fast: 0B TLAB totals: thrds: 1 refills: 21 max: 21 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 40B max: 40B fast: 0B max: 0B [GC (Allocation Failure) 2632K->584K(134656K), 0.0005630 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 1.59615 6538KB refills: 41 waste 0.0% gc: 0B slow: 664B fast: 0B TLAB totals: thrds: 1 refills: 41 max: 41 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 664B max: 664B fast: 0B max: 0B [GC (Allocation Failure) 4680K->653K(134656K), 0.0005840 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 1.38784 5685KB refills: 41 waste 0.0% gc: 0B slow: 664B fast: 0B TLAB totals: thrds: 1 refills: 41 max: 41 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 664B max: 664B fast: 0B max: 0B [GC (Allocation Failure) 4749K->573K(138752K), 0.0002190 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 1.25244 10260KB refills: 82 waste 0.0% gc: 0B slow: 1328B fast: 0B TLAB totals: thrds: 1 refills: 82 max: 82 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 1328B max: 1328B fast: 0B max: 0B [GC (Allocation Failure) 8765K->573K(138752K), 0.0002610 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 1.16443 9539KB refills: 82 waste 0.0% gc: 0B slow: 1328B fast: 0B TLAB totals: thrds: 1 refills: 82 max: 82 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 1328B max: 1328B fast: 0B max: 0B [GC (Allocation Failure) 8765K->573K(143872K), 0.0002220 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 1.10722 14739KB refills: 134 waste 0.0% gc: 0B slow: 2152B fast: 0B TLAB totals: thrds: 1 refills: 134 max: 134 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 2152B max: 2152B fast: 0B max: 0B [GC (Allocation Failure) 13885K->573K(143872K), 0.0003430 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 1.07201 14271KB refills: 134 waste 0.0% gc: 0B slow: 2152B fast: 0B TLAB totals: thrds: 1 refills: 134 max: 134 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 2152B max: 2152B fast: 0B max: 0B [GC (Allocation Failure) 13885K->573K(152064K), 0.0002860 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 1.04912 22560KB refills: 215 waste 0.0% gc: 0B slow: 3456B fast: 0B TLAB totals: thrds: 1 refills: 215 max: 215 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 3456B max: 3456B fast: 0B max: 0B [GC (Allocation Failure) 22077K->573K(152064K), 0.0003170 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 1.03186 22189KB refills: 215 waste 0.0% gc: 0B slow: 3456B fast: 0B TLAB totals: thrds: 1 refills: 215 max: 215 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 3456B max: 3456B fast: 0B max: 0B [GC (Allocation Failure) 22077K->573K(165376K), 0.0007820 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 1.02064 35535KB refills: 349 waste 0.0% gc: 0B slow: 5584B fast: 0B TLAB totals: thrds: 1 refills: 349 max: 349 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 5584B max: 5584B fast: 0B max: 0B [GC (Allocation Failure) 35389K->573K(165376K), 0.0003020 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 1.01426 35313KB refills: 349 waste 0.0% gc: 0B slow: 5584B fast: 0B TLAB totals: thrds: 1 refills: 349 max: 349 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 5584B max: 5584B fast: 0B max: 0B [GC (Allocation Failure) 35389K->573K(186368K), 0.0002460 secs] TLAB: gc thread: 0x00007f9439001800 [id: 9987] desired_size: 100KB slow allocs: 0 refill waste: 1024B alloc: 1.01012 56373KB refills: 558 waste 0.0% gc: 0B slow: 8936B fast: 0B TLAB totals: thrds: 1 refills: 558 max: 558 slow allocs: 0 max 0 waste: 0.0% gc: 0B max: 0B slow: 8936B max: 8936B fast: 0B max: 0B [GC (Allocation Failure) 56381K->573K(186368K), 0.0003230 secs]
说明:
desired_size 为 TLAB 大小,通过 -XX:TLABSize=102400=100KB 设置,slow allocs 代表从上一次新生代 GC 到现在慢回收的次数(TLAB 空闲空间因为太小,导致将大对象分配到堆上的情况),