本篇文章基于V0.16 JOLSample_23_Roots
本例演示了VM如何遍历根集.
在GC过程中,需要从某个地方开始遍历对象可达图。根集是本质上可达的对象集。静态字段或者本地变量都是根集的一部分。
然后我们构建一个对象环,让这个环上的对象相互引用,最后把第一个对象引用到本地变量上,其他的都断开连接。
这将具有使环的不同部分位于根集合中的效果,这最终将改变内存中的环布局
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 public class JOLSample_23_Roots { static volatile Object sink; public interface L { L link () ; void bind (L l) ; } public static abstract class AL implements L { L l; public L link () { return l; } public void bind (L l) { this .l = l; } } public static class L1 extends AL {} public static class L2 extends AL {} public static class L3 extends AL {} public static class L4 extends AL {} public static class L5 extends AL {} public static class L6 extends AL {} public static void main (String[] args) { out.println(VM.current().details()); PrintWriter pw = new PrintWriter(System.out, true ); L l1 = new L1(); L l2 = new L2(); L l3 = new L3(); L l4 = new L4(); L l5 = new L5(); L l6 = new L6(); l1.bind(l2); l2.bind(l3); l3.bind(l4); l4.bind(l5); l5.bind(l6); l6.bind(l1); L r = l1; l1 = l2 = l3 = l4 = l5 = l6 = null ; long lastAddr = VM.current().addressOf(r); pw.printf("Fresh object is at %x%n" , lastAddr); int moves = 0 ; for (int i = 0 ; i < 100000 ; i++) { L s = r; while (!((s = s.link()) instanceof L1)) ; long cur = VM.current().addressOf(s); s = null ; if (cur != lastAddr) { moves++; pw.printf("*** Move %2d, L1 is at %x%n" , moves, cur); pw.println("*** Root is " + r.getClass()); pw.println(GraphLayout.parseInstance(r).toPrintable()); Random random = new Random(); for (int c = 0 ; c < random.nextInt(100 ); c++) { r = r.link(); } lastAddr = cur; } for (int c = 0 ; c < 10000 ; c++) { sink = new Object(); } } pw.close(); } }
运行结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 # Running 64 -bit HotSpot VM. # Using compressed oop with 3 -bit shift. # Using compressed klass with 3 -bit shift. # WARNING | Compressed references base/shifts are guessed by the experiment! # WARNING | Therefore, computed addresses are just guesses, and ARE NOT RELIABLE. # WARNING | Make sure to attach Serviceability Agent to get the reliable addresses. # Objects are 8 bytes aligned. # Field sizes by type: 4 , 1 , 1 , 2 , 2 , 4 , 4 , 8 , 8 [bytes] # Array element sizes: 4 , 1 , 1 , 2 , 2 , 4 , 4 , 8 , 8 [bytes] Fresh object is at 76bd956f8 *** Move 1 , L1 is at 76eb18178 *** Root is class org .openjdk .jol .samples .JOLSample_23_Roots $L1 org .openjdk .jol .samples .JOLSample_23_Roots $L1 @43556938d object externals : ADDRESS SIZE TYPE PATH VALUE 76eb18178 16 org .openjdk .jol .samples .JOLSample_23_Roots $L1 (object ) 76eb18188 68776 (something else ) (somewhere else ) (something else ) 76eb28e30 16 org .openjdk .jol .samples .JOLSample_23_Roots $L2 .l (object ) 76eb28e40 16 org .openjdk .jol .samples .JOLSample_23_Roots $L3 .l .l (object ) 76eb28e50 16 org .openjdk .jol .samples .JOLSample_23_Roots $L4 .l .l .l (object ) 76eb28e60 16 org .openjdk .jol .samples .JOLSample_23_Roots $L5 .l .l .l .l (object ) 76eb28e70 16 org .openjdk .jol .samples .JOLSample_23_Roots $L6 .l .l .l .l .l (object ) Addresses are stable after 1 tries .*** Move 2, L1 is at 76f5ec3c0 *** Root is class org .openjdk .jol .samples .JOLSample_23_Roots $L4 org .openjdk .jol .samples .JOLSample_23_Roots $L4 @47089e5fd object externals : ADDRESS SIZE TYPE PATH VALUE 76f590260 16 org .openjdk .jol .samples .JOLSample_23_Roots $L4 (object ) 76f590270 377136 (something else ) (somewhere else ) (something else ) 76f5ec3a0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L5 .l (object ) 76f5ec3b0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L6 .l .l (object ) 76f5ec3c0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L1 .l .l .l (object ) 76f5ec3d0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L2 .l .l .l .l (object ) 76f5ec3e0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L3 .l .l .l .l .l (object ) Addresses are stable after 1 tries .*** Move 3, L1 is at 76eb286f0 *** Root is class org .openjdk .jol .samples .JOLSample_23_Roots $L2 org .openjdk .jol .samples .JOLSample_23_Roots $L2 @532760d8d object externals : ADDRESS SIZE TYPE PATH VALUE 76eb20000 16 org .openjdk .jol .samples .JOLSample_23_Roots $L2 (object ) 76eb20010 34464 (something else ) (somewhere else ) (something else ) 76eb286b0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L3 .l (object ) 76eb286c0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L4 .l .l (object ) 76eb286d0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L5 .l .l .l (object ) 76eb286e0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L6 .l .l .l .l (object ) 76eb286f0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L1 .l .l .l .l .l (object ) Addresses are stable after 1 tries .*** Move 4, L1 is at 7736031a8 *** Root is class org .openjdk .jol .samples .JOLSample_23_Roots $L6 org .openjdk .jol .samples .JOLSample_23_Roots $L6 @4c3e4790d object externals : ADDRESS SIZE TYPE PATH VALUE 773580f20 16 org .openjdk .jol .samples .JOLSample_23_Roots $L6 (object ) 773580f30 533112 (something else ) (somewhere else ) (something else ) 7736031a8 16 org .openjdk .jol .samples .JOLSample_23_Roots $L1 .l (object ) 7736031b8 16 org .openjdk .jol .samples .JOLSample_23_Roots $L2 .l .l (object ) 7736031c8 16 org .openjdk .jol .samples .JOLSample_23_Roots $L3 .l .l .l (object ) 7736031d8 16 org .openjdk .jol .samples .JOLSample_23_Roots $L4 .l .l .l .l (object ) 7736031e8 16 org .openjdk .jol .samples .JOLSample_23_Roots $L5 .l .l .l .l .l (object ) Addresses are stable after 1 tries .*** Move 5, L1 is at 772b568c0 *** Root is class org .openjdk .jol .samples .JOLSample_23_Roots $L5 org .openjdk .jol .samples .JOLSample_23_Roots $L5 @68f7aae2d object externals : ADDRESS SIZE TYPE PATH VALUE 772b201c0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L5 (object ) 772b201d0 222944 (something else ) (somewhere else ) (something else ) 772b568b0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L6 .l (object ) 772b568c0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L1 .l .l (object ) 772b568d0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L2 .l .l .l (object ) 772b568e0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L3 .l .l .l .l (object ) 772b568f0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L4 .l .l .l .l .l (object ) Addresses are stable after 1 tries .*** Move 6, L1 is at 77adbe8e0 *** Root is class org .openjdk .jol .samples .JOLSample_23_Roots $L6 org .openjdk .jol .samples .JOLSample_23_Roots $L6 @4c3e4790d object externals : ADDRESS SIZE TYPE PATH VALUE 77ada0178 16 org .openjdk .jol .samples .JOLSample_23_Roots $L6 (object ) 77ada0188 124760 (something else ) (somewhere else ) (something else ) 77adbe8e0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L1 .l (object ) 77adbe8f0 16 org .openjdk .jol .samples .JOLSample_23_Roots $L2 .l .l (object ) 77adbe900 16 org .openjdk .jol .samples .JOLSample_23_Roots $L3 .l .l .l (object ) 77adbe910 16 org .openjdk .jol .samples .JOLSample_23_Roots $L4 .l .l .l .l (object ) 77adbe920 16 org .openjdk .jol .samples .JOLSample_23_Roots $L5 .l .l .l .l .l (object ) Addresses are stable after 1 tries .*** Move 7, L1 is at 6c002e270 *** Root is class org .openjdk .jol .samples .JOLSample_23_Roots $L4 org .openjdk .jol .samples .JOLSample_23_Roots $L4 @47089e5fd object externals : ADDRESS SIZE TYPE PATH VALUE 6c001c010 16 org .openjdk .jol .samples .JOLSample_23_Roots $L4 (object ) 6c001c020 74288 (something else ) (somewhere else ) (something else ) 6c002e250 16 org .openjdk .jol .samples .JOLSample_23_Roots $L5 .l (object ) 6c002e260 16 org .openjdk .jol .samples .JOLSample_23_Roots $L6 .l .l (object ) 6c002e270 16 org .openjdk .jol .samples .JOLSample_23_Roots $L1 .l .l .l (object ) 6c002e280 16 org .openjdk .jol .samples .JOLSample_23_Roots $L2 .l .l .l .l (object ) 6c002e290 16 org .openjdk .jol .samples .JOLSample_23_Roots $L3 .l .l .l .l .l (object ) Addresses are stable after 1 tries .
我将代码画了个流程图出来演示一下