test/gc/g1/TestGreyReclaimedHumongousObjects.java

Mon, 06 Nov 2017 16:51:47 +0800

author
aoqi
date
Mon, 06 Nov 2017 16:51:47 +0800
changeset 7997
6cbff0651f1a
parent 7830
b7c8142a9e0b
permissions
-rw-r--r--

[Code Reorganization] remove trailing whitespace to pass jcheck test

kbarrett@7830 1 /*
kbarrett@7830 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
kbarrett@7830 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
kbarrett@7830 4 *
kbarrett@7830 5 * This code is free software; you can redistribute it and/or modify it
kbarrett@7830 6 * under the terms of the GNU General Public License version 2 only, as
kbarrett@7830 7 * published by the Free Software Foundation.
kbarrett@7830 8 *
kbarrett@7830 9 * This code is distributed in the hope that it will be useful, but WITHOUT
kbarrett@7830 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
kbarrett@7830 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kbarrett@7830 12 * version 2 for more details (a copy is included in the LICENSE file that
kbarrett@7830 13 * accompanied this code).
kbarrett@7830 14 *
kbarrett@7830 15 * You should have received a copy of the GNU General Public License version
kbarrett@7830 16 * 2 along with this work; if not, write to the Free Software Foundation,
kbarrett@7830 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
kbarrett@7830 18 *
kbarrett@7830 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
kbarrett@7830 20 * or visit www.oracle.com if you need additional information or have any
kbarrett@7830 21 * questions.
kbarrett@7830 22 */
kbarrett@7830 23
kbarrett@7830 24 /*
kbarrett@7830 25 * @test TestGreyReclaimedHumongousObjects.java
kbarrett@7830 26 * @bug 8069367
kbarrett@7830 27 * @requires vm.gc == "G1" | vm.gc == "null"
kbarrett@7830 28 * @summary Test handling of marked but unscanned reclaimed humongous objects.
kbarrett@7830 29 * @key gc
kbarrett@7830 30 * @run main/othervm -XX:+UseG1GC -Xss32m -Xmx128m -XX:G1HeapRegionSize=1m
kbarrett@7830 31 * -XX:+UnlockExperimentalVMOptions
kbarrett@7830 32 * -XX:+G1EagerReclaimHumongousObjects
kbarrett@7830 33 * -XX:+G1EagerReclaimHumongousObjectsWithStaleRefs
kbarrett@7830 34 * TestGreyReclaimedHumongousObjects 1048576 90
kbarrett@7830 35 */
kbarrett@7830 36
kbarrett@7830 37 // This test spawns a bunch of threads, each of them rapidly
kbarrett@7830 38 // allocating large objects and storing them into a circular buffer
kbarrett@7830 39 // associated with the thread. The circular buffer results in these
kbarrett@7830 40 // objects becoming dead in fairly short order.
kbarrett@7830 41 //
kbarrett@7830 42 // The situation we're trying to provoke is
kbarrett@7830 43 //
kbarrett@7830 44 // (1) A humongous object H is marked and added to the mark stack.
kbarrett@7830 45 //
kbarrett@7830 46 // (2) An evacuation pause determines H is no longer live, and
kbarrett@7830 47 // reclaims it. This occurs before concurrent marking has gotten
kbarrett@7830 48 // around to processing the mark stack entry for H.
kbarrett@7830 49 //
kbarrett@7830 50 // (3) Concurrent marking processes the mark stack entry for H. The
kbarrett@7830 51 // bug is that it would attempt to scan the now dead object.
kbarrett@7830 52 //
kbarrett@7830 53 // Unfortunately, this test is *very* sensitive to configuration.
kbarrett@7830 54 // Among the parameters that affect whether / how often we'll get into
kbarrett@7830 55 // the desired situation within a reasonable amount of time are:
kbarrett@7830 56 //
kbarrett@7830 57 // - THREAD_COUNT: The number of allocating threads.
kbarrett@7830 58 //
kbarrett@7830 59 // - OLD_COUNT: The number of objects each thread keeps.
kbarrett@7830 60 //
kbarrett@7830 61 // - MAX_MEMORY: The maximum heap size.
kbarrett@7830 62 //
kbarrett@7830 63 // - G1HeapRegionSize
kbarrett@7830 64 //
kbarrett@7830 65 // - The size of the objects being allocated.
kbarrett@7830 66 //
kbarrett@7830 67 // The parameter values specified here:
kbarrett@7830 68 //
kbarrett@7830 69 // - THREAD_COUNT = 12
kbarrett@7830 70 // - OLD_COUNT == 4
kbarrett@7830 71 // - MAX_MEMORY == 128m
kbarrett@7830 72 // - G1HeapRegionSize = 1m
kbarrett@7830 73 // - Object size = 1048576 (2 regions after header overhead and roundup)
kbarrett@7830 74 //
kbarrett@7830 75 // seems to work well at provoking the desired state fairly quickly.
kbarrett@7830 76 // Even relatively small perturbations may change that. The key
kbarrett@7830 77 // factors seem to be keeping the heap mostly full of live objects but
kbarrett@7830 78 // having them become dead fairly quickly.
kbarrett@7830 79
kbarrett@7830 80 import java.util.Date;
kbarrett@7830 81 import java.util.concurrent.ExecutorService;
kbarrett@7830 82 import java.util.concurrent.Executors;
kbarrett@7830 83 import java.util.concurrent.ThreadFactory;
kbarrett@7830 84 import java.util.concurrent.TimeUnit;
kbarrett@7830 85 import sun.management.ManagementFactoryHelper;
kbarrett@7830 86 import com.sun.management.HotSpotDiagnosticMXBean;
kbarrett@7830 87 import com.sun.management.VMOption;
kbarrett@7830 88
kbarrett@7830 89 public class TestGreyReclaimedHumongousObjects {
kbarrett@7830 90
kbarrett@7830 91 static class NamedThreadFactory implements ThreadFactory {
kbarrett@7830 92 private int threadNum = 0;
kbarrett@7830 93
kbarrett@7830 94 @Override
kbarrett@7830 95 public Thread newThread(Runnable r) {
kbarrett@7830 96 return new Thread(r, THREAD_NAME + (threadNum++));
kbarrett@7830 97 }
kbarrett@7830 98 }
kbarrett@7830 99
kbarrett@7830 100 static class Runner extends Thread {
kbarrett@7830 101 private final Date startDate = new Date();
kbarrett@7830 102 private final int obj_size;
kbarrett@7830 103 private final Object[] old_garbage;
kbarrett@7830 104 private int old_index = 0;
kbarrett@7830 105
kbarrett@7830 106 public Runner(int obj_size) {
kbarrett@7830 107 this.obj_size = obj_size;
kbarrett@7830 108 old_garbage = new Object[OLD_COUNT];
kbarrett@7830 109 }
kbarrett@7830 110
kbarrett@7830 111 private void allocate_garbage() {
kbarrett@7830 112 byte[] garbage = new byte[obj_size];
kbarrett@7830 113 old_garbage[Math.abs(++old_index % OLD_COUNT)] = garbage;
kbarrett@7830 114 }
kbarrett@7830 115
kbarrett@7830 116 @Override
kbarrett@7830 117 public void run() {
kbarrett@7830 118 try {
kbarrett@7830 119 while (!isInterrupted()) {
kbarrett@7830 120 allocate_garbage();
kbarrett@7830 121 Thread.sleep(0); // Yield, to ensure interruptable.
kbarrett@7830 122 }
kbarrett@7830 123 } catch (InterruptedException e) {
kbarrett@7830 124 System.out.println("Aborted after "
kbarrett@7830 125 + (new Date().getTime() - startDate.getTime())
kbarrett@7830 126 + " ms");
kbarrett@7830 127 interrupt();
kbarrett@7830 128 }
kbarrett@7830 129 }
kbarrett@7830 130 }
kbarrett@7830 131
kbarrett@7830 132 public static void main(String[] args) throws Exception {
kbarrett@7830 133 HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
kbarrett@7830 134
kbarrett@7830 135 System.out.println("Max memory= " + MAX_MEMORY + " bytes");
kbarrett@7830 136
kbarrett@7830 137 int obj_size = 0;
kbarrett@7830 138 long seconds_to_run = 0;
kbarrett@7830 139 if (args.length != 2) {
kbarrett@7830 140 throw new RuntimeException("Object size argument must be supplied");
kbarrett@7830 141 } else {
kbarrett@7830 142 obj_size = Integer.parseInt(args[0]);
kbarrett@7830 143 seconds_to_run = Integer.parseInt(args[1]);
kbarrett@7830 144 }
kbarrett@7830 145 System.out.println("Objects size= " + obj_size + " bytes");
kbarrett@7830 146 System.out.println("Seconds to run=" + seconds_to_run);
kbarrett@7830 147
kbarrett@7830 148 int region_size =
kbarrett@7830 149 Integer.parseInt(diagnostic.getVMOption("G1HeapRegionSize").getValue());
kbarrett@7830 150 if (obj_size < (region_size / 2)) {
kbarrett@7830 151 throw new RuntimeException("Object size " + obj_size +
kbarrett@7830 152 " is not humongous with region size " + region_size);
kbarrett@7830 153 }
kbarrett@7830 154
kbarrett@7830 155 ExecutorService executor =
kbarrett@7830 156 Executors.newFixedThreadPool(THREAD_COUNT, new NamedThreadFactory());
kbarrett@7830 157 System.out.println("Starting " + THREAD_COUNT + " threads");
kbarrett@7830 158
kbarrett@7830 159 for (int i = 0; i < THREAD_COUNT; i++) {
kbarrett@7830 160 executor.execute(new Runner(obj_size));
kbarrett@7830 161 }
kbarrett@7830 162
kbarrett@7830 163 Thread.sleep(seconds_to_run * 1000);
kbarrett@7830 164 executor.shutdownNow();
kbarrett@7830 165
kbarrett@7830 166 if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
kbarrett@7830 167 System.err.println("Thread pool did not terminate after 10 seconds after shutdown");
kbarrett@7830 168 }
kbarrett@7830 169 }
kbarrett@7830 170
kbarrett@7830 171 private static final long MAX_MEMORY = Runtime.getRuntime().maxMemory();
kbarrett@7830 172 private static final int OLD_COUNT = 4;
kbarrett@7830 173 private static final int THREAD_COUNT = 12;
kbarrett@7830 174 private static final String THREAD_NAME = "TestGreyRH-";
kbarrett@7830 175 }
kbarrett@7830 176

mercurial