Path: blob/master/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.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:+ShenandoahDegeneratedGC33* TestPauseNotifications34*35* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions36* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive37* -XX:-ShenandoahDegeneratedGC38* TestPauseNotifications39*/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* TestPauseNotifications50*/5152/*53* @test id=adaptive54* @summary Check that MX notifications are reported for all cycles55* @library /test/lib /56* @requires vm.gc.Shenandoah57*58* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions59* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive60* TestPauseNotifications61*/6263/*64* @test id=static65* @summary Check that MX notifications are reported for all cycles66* @library /test/lib /67* @requires vm.gc.Shenandoah68*69* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions70* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static71* TestPauseNotifications72*/7374/*75* @test id=compact76* @summary Check that MX notifications are reported for all cycles77* @library /test/lib /78* @requires vm.gc.Shenandoah79*80* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions81* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact82* TestPauseNotifications83*/8485/*86* @test id=iu87* @summary Check that MX notifications are reported for all cycles88* @library /test/lib /89* @requires vm.gc.Shenandoah90*91* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions92* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive93* TestPauseNotifications94*95* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions96* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu97* TestPauseNotifications98*/99100import java.util.*;101import java.util.concurrent.atomic.*;102import javax.management.*;103import java.lang.management.*;104import javax.management.openmbean.*;105106import jdk.test.lib.Utils;107108import com.sun.management.GarbageCollectionNotificationInfo;109110public class TestPauseNotifications {111112static final long HEAP_MB = 128; // adjust for test configuration above113static final long TARGET_MB = Long.getLong("target", 2_000); // 2 Gb allocation114115static volatile Object sink;116117public static void main(String[] args) throws Exception {118final long startTime = System.currentTimeMillis();119120final AtomicLong pausesDuration = new AtomicLong();121final AtomicLong cyclesDuration = new AtomicLong();122final AtomicLong pausesCount = new AtomicLong();123final AtomicLong cyclesCount = 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());130131System.out.println("Received: " + info.getGcName());132133long d = info.getGcInfo().getDuration();134135String name = info.getGcName();136if (name.contains("Shenandoah")) {137if (name.equals("Shenandoah Pauses")) {138pausesCount.incrementAndGet();139pausesDuration.addAndGet(d);140} else if (name.equals("Shenandoah Cycles")) {141cyclesCount.incrementAndGet();142cyclesDuration.addAndGet(d);143} else {144throw new IllegalStateException("Unknown name: " + name);145}146}147}148}149};150151for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) {152((NotificationEmitter) bean).addNotificationListener(listener, null, null);153}154155final int size = 100_000;156long count = TARGET_MB * 1024 * 1024 / (16 + 4 * size);157158for (int c = 0; c < count; c++) {159sink = new int[size];160}161162// Look at test timeout to figure out how long we can wait without breaking into timeout.163// Default to 1/4 of the remaining time in 1s steps.164final long STEP_MS = 1000;165long spentTime = System.currentTimeMillis() - startTime;166long maxTries = (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) - spentTime) / STEP_MS / 4;167168long actualPauses = 0;169long actualCycles = 0;170171// Wait until enough notifications are accrued to match minimum boundary.172long minExpected = 10;173174long tries = 0;175while (tries++ < maxTries) {176actualPauses = pausesCount.get();177actualCycles = cyclesCount.get();178if (minExpected <= actualPauses && minExpected <= actualCycles) {179// Wait a little bit to catch the lingering notifications.180Thread.sleep(5000);181actualPauses = pausesCount.get();182actualCycles = cyclesCount.get();183break;184}185Thread.sleep(STEP_MS);186}187188{189String msg = "Pauses expected = [" + minExpected + "; +inf], actual = " + actualPauses;190if (minExpected <= actualPauses) {191System.out.println(msg);192} else {193throw new IllegalStateException(msg);194}195}196197{198String msg = "Cycles expected = [" + minExpected + "; +inf], actual = " + actualCycles;199if (minExpected <= actualCycles) {200System.out.println(msg);201} else {202throw new IllegalStateException(msg);203}204}205206{207long actualPauseDuration = pausesDuration.get();208long actualCycleDuration = cyclesDuration.get();209210String msg = "Pauses duration (" + actualPauseDuration + ") is expected to be not larger than cycles duration (" + actualCycleDuration + ")";211212if (actualPauseDuration <= actualCycleDuration) {213System.out.println(msg);214} else {215throw new IllegalStateException(msg);216}217}218}219}220221222