Path: blob/master/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestChurnNotifications.java
41153 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 TestChurnNotifications26* @summary Check that MX notifications are reported for all cycles27* @requires vm.gc.Shenandoah28*29* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions30* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive31* -XX:+ShenandoahDegeneratedGC -Dprecise=true32* TestChurnNotifications33*34* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions35* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive36* -XX:-ShenandoahDegeneratedGC -Dprecise=true37* TestChurnNotifications38*/3940/*41* @test TestChurnNotifications42* @summary Check that MX notifications are reported for all cycles43* @requires vm.gc.Shenandoah44*45* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions46* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive47* -Dprecise=false48* TestChurnNotifications49*/5051/*52* @test TestChurnNotifications53* @summary Check that MX notifications are reported for all cycles54* @requires vm.gc.Shenandoah55*56* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions57* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive58* -Dprecise=false59* TestChurnNotifications60*/6162/*63* @test TestChurnNotifications64* @summary Check that MX notifications are reported for all cycles65* @requires vm.gc.Shenandoah66*67* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions68* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static69* -Dprecise=false70* TestChurnNotifications71*/7273/*74* @test TestChurnNotifications75* @summary Check that MX notifications are reported for all cycles76* @requires vm.gc.Shenandoah77*78* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions79* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact80* -Dprecise=false81* TestChurnNotifications82*/8384/*85* @test TestChurnNotifications86* @summary Check that MX notifications are reported for all cycles87* @requires vm.gc.Shenandoah88*89* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions90* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive91* -Dprecise=false92* TestChurnNotifications93*94* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions95* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu96* -Dprecise=false97* TestChurnNotifications98*/99100import java.util.*;101import java.util.concurrent.atomic.*;102import javax.management.*;103import java.lang.management.*;104import javax.management.openmbean.*;105106import com.sun.management.GarbageCollectionNotificationInfo;107108public class TestChurnNotifications {109110static final long HEAP_MB = 128; // adjust for test configuration above111static final long TARGET_MB = Long.getLong("target", 2_000); // 2 Gb allocation112113// Should we track the churn precisely?114// Precise tracking is only reliable when GC is fully stop-the-world. Otherwise,115// we cannot tell, looking at heap used before/after, what was the GC churn.116static final boolean PRECISE = Boolean.getBoolean("precise");117118static final long M = 1024 * 1024;119120static volatile Object sink;121122public static void main(String[] args) throws Exception {123final AtomicLong churnBytes = new AtomicLong();124125NotificationListener listener = new NotificationListener() {126@Override127public void handleNotification(Notification n, Object o) {128if (n.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {129GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from((CompositeData) n.getUserData());130Map<String, MemoryUsage> mapBefore = info.getGcInfo().getMemoryUsageBeforeGc();131Map<String, MemoryUsage> mapAfter = info.getGcInfo().getMemoryUsageAfterGc();132133MemoryUsage before = mapBefore.get("Shenandoah");134MemoryUsage after = mapAfter.get("Shenandoah");135136if ((before != null) && (after != null)) {137long diff = before.getUsed() - after.getUsed();138if (diff > 0) {139churnBytes.addAndGet(diff);140}141}142}143}144};145146for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) {147((NotificationEmitter) bean).addNotificationListener(listener, null, null);148}149150final int size = 100_000;151long count = TARGET_MB * 1024 * 1024 / (16 + 4 * size);152153long mem = count * (16 + 4 * size);154155for (int c = 0; c < count; c++) {156sink = new int[size];157}158159System.gc();160161// Wait until notifications start arriving, and then wait some more162// to catch the ones arriving late.163while (churnBytes.get() == 0) {164Thread.sleep(1000);165}166Thread.sleep(5000);167168long actual = churnBytes.get();169170long minExpected = PRECISE ? (mem - HEAP_MB * 1024 * 1024) : 1;171long maxExpected = mem + HEAP_MB * 1024 * 1024;172173String msg = "Expected = [" + minExpected / M + "; " + maxExpected / M + "] (" + mem / M + "), actual = " + actual / M;174if (minExpected <= actual && actual <= maxExpected) {175System.out.println(msg);176} else {177throw new IllegalStateException(msg);178}179}180}181182183