|
1 | 1 | /*
|
2 |
| - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
4 | 4 | *
|
5 | 5 | * This code is free software; you can redistribute it and/or modify it
|
|
28 | 28 | * @bug 8051973
|
29 | 29 | * @summary Test to make sure that eager reclaim of humongous objects correctly clears
|
30 | 30 | * mark bitmaps at reclaim.
|
31 |
| - * @key randomness |
32 | 31 | * @requires vm.gc.G1
|
33 | 32 | * @requires vm.debug
|
34 |
| - * @library /test/lib |
| 33 | + * @library /test/lib /testlibrary / |
35 | 34 | * @modules java.base/jdk.internal.misc
|
36 | 35 | * java.management
|
| 36 | + * @build jdk.test.whitebox.WhiteBox |
| 37 | + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox |
37 | 38 | * @run driver gc.g1.TestEagerReclaimHumongousRegionsClearMarkBits
|
38 | 39 | */
|
39 | 40 |
|
40 |
| -import java.util.ArrayList; |
41 |
| -import java.util.LinkedList; |
42 |
| -import java.util.Random; |
| 41 | +import java.util.regex.Matcher; |
| 42 | +import java.util.regex.Pattern; |
43 | 43 |
|
| 44 | +import jdk.test.lib.Asserts; |
44 | 45 | import jdk.test.lib.process.OutputAnalyzer;
|
45 | 46 | import jdk.test.lib.process.ProcessTools;
|
46 |
| -import jdk.test.lib.Utils; |
47 |
| - |
48 |
| -// An object that has a few references to other instances to slow down marking. |
49 |
| -class ObjectWithSomeRefs { |
50 |
| - public ObjectWithSomeRefs other1; |
51 |
| - public ObjectWithSomeRefs other2; |
52 |
| - public ObjectWithSomeRefs other3; |
53 |
| - public ObjectWithSomeRefs other4; |
54 |
| -} |
55 |
| - |
56 |
| -class TestEagerReclaimHumongousRegionsClearMarkBitsReclaimRegionFast { |
57 |
| - public static final long MAX_NANOS_FOR_RUN = 50L * 1_000_000_000L; // The maximum runtime for the actual test. |
| 47 | +import jdk.test.whitebox.WhiteBox; |
58 | 48 |
|
59 |
| - public static final int M = 1024*1024; |
| 49 | +public class TestEagerReclaimHumongousRegionsClearMarkBits { |
| 50 | + public static void main(String[] args) throws Exception { |
| 51 | + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", |
| 52 | + "-Xmx20M", |
| 53 | + "-Xms20m", |
| 54 | + "-XX:+UnlockDiagnosticVMOptions", |
| 55 | + "-XX:+VerifyAfterGC", |
| 56 | + "-Xbootclasspath/a:.", |
| 57 | + "-Xlog:gc=debug,gc+humongous=debug", |
| 58 | + "-XX:+UnlockDiagnosticVMOptions", |
| 59 | + "-XX:+WhiteBoxAPI", |
| 60 | + TestEagerReclaimHumongousRegionsClearMarkBitsRunner.class.getName()); |
| 61 | + |
| 62 | + String log = output.getStdout(); |
| 63 | + System.out.println(log); |
| 64 | + output.shouldHaveExitValue(0); |
60 | 65 |
|
61 |
| - public static LinkedList<Object> garbageList = new LinkedList<Object>(); |
| 66 | + // Find the log output indicating that the humongous object has been reclaimed, and marked. |
| 67 | + Pattern pattern = Pattern.compile("Humongous region .* marked 1 .* reclaim candidate 1 type array 1"); |
| 68 | + Asserts.assertTrue(pattern.matcher(log).find(), "Could not find log output matching marked humongous region."); |
62 | 69 |
|
63 |
| - public static void genGarbage(Object large) { |
64 |
| - for (int i = 0; i < 64*1024; i++) { |
65 |
| - Object[] garbage = new Object[50]; |
66 |
| - garbage[0] = large; |
67 |
| - garbageList.add(garbage); |
68 |
| - } |
69 |
| - garbageList.clear(); |
| 70 | + pattern = Pattern.compile("Reclaimed humongous region .*"); |
| 71 | + Asserts.assertTrue(pattern.matcher(log).find(), "Could not find log output reclaiming humongous region"); |
70 | 72 | }
|
| 73 | +} |
71 | 74 |
|
72 |
| - public static ArrayList<ObjectWithSomeRefs> longList = new ArrayList<ObjectWithSomeRefs>(); |
| 75 | +class TestEagerReclaimHumongousRegionsClearMarkBitsRunner { |
| 76 | + private static final WhiteBox WB = WhiteBox.getWhiteBox(); |
| 77 | + private static final int M = 1024 * 1024; |
73 | 78 |
|
74 | 79 | public static void main(String[] args) {
|
| 80 | + WB.fullGC(); |
75 | 81 |
|
76 |
| - for (int i = 0; i < 16*1024; i++) { |
77 |
| - longList.add(new ObjectWithSomeRefs()); |
78 |
| - } |
79 |
| - |
80 |
| - Random rnd = Utils.getRandomInstance(); |
81 |
| - for (int i = 0; i < longList.size(); i++) { |
82 |
| - int len = longList.size(); |
83 |
| - longList.get(i).other1 = longList.get(rnd.nextInt(len)); |
84 |
| - longList.get(i).other2 = longList.get(rnd.nextInt(len)); |
85 |
| - longList.get(i).other3 = longList.get(rnd.nextInt(len)); |
86 |
| - longList.get(i).other4 = longList.get(rnd.nextInt(len)); |
87 |
| - } |
88 |
| - |
89 |
| - int[] large1 = new int[M]; |
90 |
| - int[] large2 = null; |
91 |
| - int[] large3 = null; |
92 |
| - int[] large4 = null; |
93 |
| - |
94 |
| - Object ref_from_stack = large1; |
95 |
| - |
96 |
| - long start_nanos = System.nanoTime(); |
97 |
| - |
98 |
| - for (int i = 0; i < 20; i++) { |
99 |
| - long current_nanos = System.nanoTime(); |
100 |
| - if ((current_nanos - start_nanos) > MAX_NANOS_FOR_RUN) { |
101 |
| - System.out.println("Finishing test because maximum runtime exceeded"); |
102 |
| - break; |
103 |
| - } |
104 |
| - // A set of large objects that will be reclaimed eagerly - and hopefully marked. |
105 |
| - large1 = new int[M - 20]; |
106 |
| - large2 = new int[M - 20]; |
107 |
| - large3 = new int[M - 20]; |
108 |
| - large4 = new int[M - 20]; |
109 |
| - genGarbage(large1); |
110 |
| - // Make sure that the compiler cannot completely remove |
111 |
| - // the allocation of the large object until here. |
112 |
| - System.out.println(large1 + " " + large2 + " " + large3 + " " + large4); |
113 |
| - } |
114 |
| - |
115 |
| - // Keep the reference to the first object alive. |
116 |
| - System.out.println(ref_from_stack); |
117 |
| - } |
118 |
| -} |
| 82 | + Object largeObj = new int[M]; // Humongous object. |
119 | 83 |
|
120 |
| -public class TestEagerReclaimHumongousRegionsClearMarkBits { |
121 |
| - public static void main(String[] args) throws Exception { |
122 |
| - OutputAnalyzer output = ProcessTools.executeLimitedTestJava( |
123 |
| - "-XX:+UseG1GC", |
124 |
| - "-Xms128M", |
125 |
| - "-Xmx128M", |
126 |
| - "-Xmn2M", |
127 |
| - "-XX:G1HeapRegionSize=1M", |
128 |
| - "-XX:InitiatingHeapOccupancyPercent=0", // Want to have as much as possible mark cycles. |
129 |
| - "-Xlog:gc", |
130 |
| - "-XX:+UnlockDiagnosticVMOptions", |
131 |
| - "-XX:+VerifyAfterGC", |
132 |
| - "-XX:ConcGCThreads=1", // Want to make marking as slow as possible. |
133 |
| - "-XX:+G1VerifyBitmaps", |
134 |
| - TestEagerReclaimHumongousRegionsClearMarkBitsReclaimRegionFast.class.getName()); |
135 |
| - output.shouldHaveExitValue(0); |
| 84 | + WB.concurrentGCAcquireControl(); |
| 85 | + WB.concurrentGCRunTo(WB.BEFORE_MARKING_COMPLETED); |
| 86 | + |
| 87 | + System.out.println("Large object at " + largeObj); |
| 88 | + |
| 89 | + largeObj = null; |
| 90 | + WB.youngGC(); // Should reclaim marked humongous object. |
| 91 | + |
| 92 | + WB.concurrentGCRunToIdle(); |
136 | 93 | }
|
137 | 94 | }
|
| 95 | + |
0 commit comments