|
45 | 45 | import jdk.test.lib.process.OutputAnalyzer;
|
46 | 46 | import jdk.test.lib.process.ProcessTools;
|
47 | 47 |
|
48 |
| -import java.util.Queue; |
49 |
| -import java.util.concurrent.ArrayBlockingQueue; |
| 48 | +import java.lang.ref.Reference; |
50 | 49 |
|
51 | 50 | public class TestHumongousConcurrentStartUndo {
|
52 | 51 | // Heap sizes < 224 MB are increased to 224 MB if vm_page_size == 64K to
|
@@ -80,54 +79,64 @@ public static void main(String[] args) throws Exception {
|
80 | 79 | }
|
81 | 80 |
|
82 | 81 | static class EdenObjectAllocatorWithHumongousAllocation {
|
83 |
| - private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); |
| 82 | + private static final WhiteBox WB = WhiteBox.getWhiteBox(); |
84 | 83 |
|
85 |
| - private static void allocateHumongous(int num, int objSize, Queue keeper) { |
86 |
| - for (int i = 1; i <= num; i++) { |
| 84 | + private static final int M = 1024 * 1024; |
| 85 | + // Make humongous object size 75% of region size |
| 86 | + private static final int HumongousObjectSize = |
| 87 | + (int)(HeapRegionSize * M * 0.75); |
| 88 | + // Number of objects to allocate to go above IHOP |
| 89 | + private static final int NumHumongousObjectAllocations = |
| 90 | + (int)(((HeapSize - YoungSize) * 80 / 100.0) / HeapRegionSize); |
| 91 | + |
| 92 | + |
| 93 | + private static void allocateHumongous(int num, Object[] holder) { |
| 94 | + for (int i = 0; i < num; i++) { |
87 | 95 | if (i % 10 == 0) {
|
88 | 96 | System.out.println("Allocating humongous object " + i + "/" + num +
|
89 |
| - " of size " + objSize + " bytes"); |
90 |
| - } |
91 |
| - byte[] e = new byte[objSize]; |
92 |
| - if (!keeper.offer(e)) { |
93 |
| - keeper.remove(); |
94 |
| - keeper.offer(e); |
| 97 | + " of size " + HumongousObjectSize + " bytes"); |
95 | 98 | }
|
| 99 | + holder[i % holder.length] = new byte[HumongousObjectSize]; |
96 | 100 | }
|
97 | 101 | }
|
98 | 102 |
|
99 |
| - public static void main(String [] args) throws Exception { |
100 |
| - final int M = 1024 * 1024; |
101 |
| - // Make humongous object size 75% of region size |
102 |
| - final int humongousObjectSize = |
103 |
| - (int)(HeapRegionSize * M * 0.75); |
| 103 | + private static void runConcurrentUndoCycle() { |
| 104 | + // Start from an "empty" heap. |
| 105 | + WB.fullGC(); |
| 106 | + // The queue only holds one element, so only one humongous object |
| 107 | + // will be reachable and the concurrent operation should be undone. |
| 108 | + allocateHumongous(NumHumongousObjectAllocations, new Object[1]); |
| 109 | + Helpers.waitTillCMCFinished(WB, 1); |
| 110 | + } |
104 | 111 |
|
105 |
| - // Number of objects to allocate to go above IHOP |
106 |
| - final int humongousObjectAllocations = |
107 |
| - (int)(((HeapSize - YoungSize) * 80 / 100.0) / HeapRegionSize); |
| 112 | + private static void runConcurrentMarkCycle() { |
| 113 | + Object[] a = new Object[NumHumongousObjectAllocations]; |
| 114 | + // Start from an "empty" heap. |
| 115 | + WB.fullGC(); |
| 116 | + // Try to trigger a concurrent mark cycle. Block concurrent operation |
| 117 | + // while we are allocating more humongous objects than the IHOP threshold. |
| 118 | + // After releasing control, trigger the full cycle. |
| 119 | + try { |
| 120 | + System.out.println("Acquire CM control"); |
| 121 | + WB.concurrentGCAcquireControl(); |
| 122 | + allocateHumongous(NumHumongousObjectAllocations, a); |
| 123 | + } finally { |
| 124 | + System.out.println("Release CM control"); |
| 125 | + WB.concurrentGCReleaseControl(); |
| 126 | + } |
| 127 | + // At this point we kept NumHumongousObjectAllocations humongous objects live |
| 128 | + // in "a" which is larger than the IHOP threshold. Another dummy humongous |
| 129 | + // allocation must trigger a concurrent cycle that is not an Undo Cycle. |
| 130 | + allocateHumongous(1, new Object[1]); |
| 131 | + Helpers.waitTillCMCFinished(WB, 1); |
108 | 132 |
|
109 |
| - ArrayBlockingQueue a; |
| 133 | + Reference.reachabilityFence(a); |
| 134 | + } |
| 135 | + |
| 136 | + public static void main(String [] args) throws Exception { |
110 | 137 | for (int iterate = 0; iterate < 3; iterate++) {
|
111 |
| - // Start from an "empty" heap. |
112 |
| - WHITE_BOX.fullGC(); |
113 |
| - // The queue only holds one element, so only one humongous object |
114 |
| - // will be reachable and the concurrent operation should be undone. |
115 |
| - a = new ArrayBlockingQueue(1); |
116 |
| - allocateHumongous(humongousObjectAllocations, humongousObjectSize, a); |
117 |
| - Helpers.waitTillCMCFinished(WHITE_BOX, 1); |
118 |
| - a = null; |
119 |
| - |
120 |
| - // Start from an "empty" heap. |
121 |
| - WHITE_BOX.fullGC(); |
122 |
| - // The queue only holds all elements, so all humongous object |
123 |
| - // will be reachable and the concurrent operation should be a regular mark. |
124 |
| - a = new ArrayBlockingQueue(humongousObjectAllocations); |
125 |
| - allocateHumongous(humongousObjectAllocations, humongousObjectSize, a); |
126 |
| - Helpers.waitTillCMCFinished(WHITE_BOX, 1); |
127 |
| - a = null; |
128 |
| - |
129 |
| - allocateHumongous(1, humongousObjectSize, new ArrayBlockingQueue(1)); |
130 |
| - Helpers.waitTillCMCFinished(WHITE_BOX, 1); |
| 138 | + runConcurrentUndoCycle(); |
| 139 | + runConcurrentMarkCycle(); |
131 | 140 | }
|
132 | 141 | }
|
133 | 142 | }
|
|
0 commit comments