Path: blob/master/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestChurnNotifications.java
64507 views
/*1* Copyright (c) 2018, Red Hat, Inc. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324/*25* @test id=passive26* @summary Check that MX notifications are reported for all cycles27* @library /test/lib /28* @requires vm.gc.Shenandoah29*30* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions31* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive32* -XX:+ShenandoahDegeneratedGC -Dprecise=true33* TestChurnNotifications34*35* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions36* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive37* -XX:-ShenandoahDegeneratedGC -Dprecise=true38* TestChurnNotifications39*/4041/*42* @test id=aggressive43* @summary Check that MX notifications are reported for all cycles44* @library /test/lib /45* @requires vm.gc.Shenandoah46*47* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions48* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive49* -Dprecise=false50* TestChurnNotifications51*/5253/*54* @test id=adaptive55* @summary Check that MX notifications are reported for all cycles56* @library /test/lib /57* @requires vm.gc.Shenandoah58*59* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions60* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive61* -Dprecise=false62* TestChurnNotifications63*/6465/*66* @test id=static67* @summary Check that MX notifications are reported for all cycles68* @library /test/lib /69* @requires vm.gc.Shenandoah70*71* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions72* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static73* -Dprecise=false74* TestChurnNotifications75*/7677/*78* @test id=compact79* @summary Check that MX notifications are reported for all cycles80* @library /test/lib /81* @requires vm.gc.Shenandoah82*83* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions84* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact85* -Dprecise=false86* TestChurnNotifications87*/8889/*90* @test id=iu91* @summary Check that MX notifications are reported for all cycles92* @library /test/lib /93* @requires vm.gc.Shenandoah94*95* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions96* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive97* -Dprecise=false98* TestChurnNotifications99*100* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions101* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu102* -Dprecise=false103* TestChurnNotifications104*/105106import java.util.*;107import java.util.concurrent.atomic.*;108import javax.management.*;109import java.lang.management.*;110import javax.management.openmbean.*;111112import jdk.test.lib.Utils;113114import com.sun.management.GarbageCollectionNotificationInfo;115116public class TestChurnNotifications {117118static final long HEAP_MB = 128; // adjust for test configuration above119static final long TARGET_MB = Long.getLong("target", 2_000); // 2 Gb allocation120121// Should we track the churn precisely?122// Precise tracking is only reliable when GC is fully stop-the-world. Otherwise,123// we cannot tell, looking at heap used before/after, what was the GC churn.124static final boolean PRECISE = Boolean.getBoolean("precise");125126static final long M = 1024 * 1024;127128static volatile Object sink;129130public static void main(String[] args) throws Exception {131final long startTime = System.currentTimeMillis();132133final AtomicLong churnBytes = new AtomicLong();134135NotificationListener listener = new NotificationListener() {136@Override137public void handleNotification(Notification n, Object o) {138if (n.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {139GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from((CompositeData) n.getUserData());140Map<String, MemoryUsage> mapBefore = info.getGcInfo().getMemoryUsageBeforeGc();141Map<String, MemoryUsage> mapAfter = info.getGcInfo().getMemoryUsageAfterGc();142143MemoryUsage before = mapBefore.get("Shenandoah");144MemoryUsage after = mapAfter.get("Shenandoah");145146if ((before != null) && (after != null)) {147long diff = before.getUsed() - after.getUsed();148if (diff > 0) {149churnBytes.addAndGet(diff);150}151}152}153}154};155156for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) {157((NotificationEmitter) bean).addNotificationListener(listener, null, null);158}159160final int size = 100_000;161long count = TARGET_MB * 1024 * 1024 / (16 + 4 * size);162163long mem = count * (16 + 4 * size);164165for (int c = 0; c < count; c++) {166sink = new int[size];167}168169System.gc();170171long minExpected = PRECISE ? (mem - HEAP_MB * 1024 * 1024) : 1;172long maxExpected = mem + HEAP_MB * 1024 * 1024;173long actual = 0;174175// Look at test timeout to figure out how long we can wait without breaking into timeout.176// Default to 1/4 of the remaining time in 1s steps.177final long STEP_MS = 1000;178long spentTime = System.currentTimeMillis() - startTime;179long maxTries = (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) - spentTime) / STEP_MS / 4;180181// Wait until enough notifications are accrued to match minimum boundary.182long tries = 0;183while (tries++ < maxTries) {184actual = churnBytes.get();185if (minExpected <= actual) {186// Wait some more to test if we are breaking the maximum boundary.187Thread.sleep(5000);188actual = churnBytes.get();189break;190}191Thread.sleep(STEP_MS);192}193194String msg = "Expected = [" + minExpected / M + "; " + maxExpected / M + "] (" + mem / M + "), actual = " + actual / M;195if (minExpected <= actual && actual <= maxExpected) {196System.out.println(msg);197} else {198throw new IllegalStateException(msg);199}200}201}202203204