--- old/src/java.base/share/classes/module-info.java 2020-03-05 14:19:30.223221511 +0800
+++ new/src/java.base/share/classes/module-info.java 2020-03-05 14:19:30.090216666 +0800
@@ -151,7 +151,8 @@
java.rmi,
jdk.jlink,
jdk.net,
- jdk.incubator.foreign;
+ jdk.incubator.foreign,
+ jdk.jfr;
exports jdk.internal.access.foreign to
jdk.incubator.foreign;
exports jdk.internal.event to
--- old/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java 2020-03-05 14:19:30.869245045 +0800
+++ new/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java 2020-03-05 14:19:30.737240236 +0800
@@ -28,9 +28,14 @@
import java.util.ArrayList;
import java.util.List;
+import jdk.internal.access.JavaNioAccess;
+import jdk.internal.access.SharedSecrets;
+import jdk.internal.misc.VM;
+
import jdk.jfr.Event;
import jdk.jfr.events.ActiveRecordingEvent;
import jdk.jfr.events.ActiveSettingEvent;
+import jdk.jfr.events.DirectMemoryStatisticsEvent;
import jdk.jfr.events.ErrorThrownEvent;
import jdk.jfr.events.ExceptionStatisticsEvent;
import jdk.jfr.events.ExceptionThrownEvent;
@@ -73,7 +78,8 @@
jdk.internal.event.SecurityPropertyModificationEvent.class,
jdk.internal.event.TLSHandshakeEvent.class,
jdk.internal.event.X509CertificateEvent.class,
- jdk.internal.event.X509ValidationEvent.class
+ jdk.internal.event.X509ValidationEvent.class,
+ DirectMemoryStatisticsEvent.class
};
// This is a list of the classes with instrumentation code that should be applied.
@@ -90,6 +96,7 @@
private static final Class>[] targetClasses = new Class>[instrumentationClasses.length];
private static final JVM jvm = JVM.getJVM();
private static final Runnable emitExceptionStatistics = JDKEvents::emitExceptionStatistics;
+ private static final Runnable emitDirectMemoryStatistics = JDKEvents::emitDirectMemoryStatistics;
private static boolean initializationTriggered;
@SuppressWarnings("unchecked")
@@ -104,6 +111,7 @@
}
initializationTriggered = true;
RequestEngine.addTrustedJDKHook(ExceptionStatisticsEvent.class, emitExceptionStatistics);
+ RequestEngine.addTrustedJDKHook(DirectMemoryStatisticsEvent.class, emitDirectMemoryStatistics);
}
} catch (Exception e) {
Logger.log(LogTag.JFR_SYSTEM, LogLevel.WARN, "Could not initialize JDK events. " + e.getMessage());
@@ -160,5 +168,16 @@
public static void remove() {
RequestEngine.removeHook(JDKEvents::emitExceptionStatistics);
+ RequestEngine.removeHook(emitDirectMemoryStatistics);
+ }
+
+ private static void emitDirectMemoryStatistics() {
+ DirectMemoryStatisticsEvent e = new DirectMemoryStatisticsEvent();
+ JavaNioAccess.BufferPool pool = SharedSecrets.getJavaNioAccess().getDirectBufferPool();
+ e.count = pool.getCount();
+ e.totalCapacity = pool.getTotalCapacity();
+ e.memoryUsed = pool.getMemoryUsed();
+ e.maxCapacity = VM.maxDirectMemory();
+ e.commit();
}
}
--- old/src/jdk.jfr/share/conf/jfr/default.jfc 2020-03-05 14:19:31.513268506 +0800
+++ new/src/jdk.jfr/share/conf/jfr/default.jfc 2020-03-05 14:19:31.379263624 +0800
@@ -731,6 +731,10 @@
true
+
+ true
+ 5 s
+
--- old/src/jdk.jfr/share/conf/jfr/profile.jfc 2020-03-05 14:19:32.164292222 +0800
+++ new/src/jdk.jfr/share/conf/jfr/profile.jfc 2020-03-05 14:19:32.028287267 +0800
@@ -731,6 +731,10 @@
true
+
+ true
+ 5 s
+
--- old/test/lib/jdk/test/lib/jfr/EventNames.java 2020-03-05 14:19:32.810315756 +0800
+++ new/test/lib/jdk/test/lib/jfr/EventNames.java 2020-03-05 14:19:32.678310947 +0800
@@ -187,6 +187,7 @@
public final static String X509Certificate = PREFIX + "X509Certificate";
public final static String X509Validation = PREFIX + "X509Validation";
public final static String SecurityProperty = PREFIX + "SecurityPropertyModification";
+ public final static String DirectMemoryStatistics = PREFIX + "DirectMemoryStatistics";
// Flight Recorder
public final static String DumpReason = PREFIX + "DumpReason";
--- /dev/null 2020-03-04 10:31:35.144410376 +0800
+++ new/src/jdk.jfr/share/classes/jdk/jfr/events/DirectMemoryStatisticsEvent.java 2020-03-05 14:19:33.326334553 +0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.events;
+
+import jdk.jfr.*;
+import jdk.jfr.internal.Type;
+
+@Name(Type.EVENT_NAME_PREFIX + "DirectMemoryStatistics")
+@Label("Direct Memory Statistics")
+@Category({ "Java Application", "Statistics" })
+@Description("Statistics of direct memory")
+public final class DirectMemoryStatisticsEvent extends AbstractJDKEvent {
+
+ @Label("Count")
+ public long count;
+
+ @Label("Total Capacity")
+ @DataAmount
+ public long totalCapacity;
+
+ @Label("Memory Used")
+ @DataAmount
+ public long memoryUsed;
+
+ @Label("Maximum Capacity")
+ @Description("Maximum direct memory capacity the process can use")
+ @DataAmount
+ public long maxCapacity;
+}
--- /dev/null 2020-03-04 10:31:35.144410376 +0800
+++ new/test/jdk/jdk/jfr/event/runtime/TestDirectMemoryStatisticsEvent.java 2020-03-05 14:19:34.024359982 +0800
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.event.runtime;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import jdk.internal.misc.VM;
+
+import jdk.jfr.Recording;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.jfr.EventNames;
+import jdk.test.lib.jfr.Events;
+
+/**
+ * @test
+ * @key jfr
+ * @requires vm.hasJFR
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @run main/othervm -XX:MaxDirectMemorySize=128m jdk.jfr.event.runtime.TestDirectMemoryStatisticsEvent
+ * @run main/othervm jdk.jfr.event.runtime.TestDirectMemoryStatisticsEvent
+ */
+public class TestDirectMemoryStatisticsEvent {
+
+ private static final String EVENT_PATH = EventNames.DirectMemoryStatistics;
+
+ public static void main(String[] args) throws Throwable {
+ try (Recording recording = new Recording()) {
+ recording.enable(EVENT_PATH);
+ recording.start();
+ int rounds = 16;
+ int size = 1 * 1024 * 1024; // 1M
+ for (int i = 0; i < rounds; i++) {
+ ByteBuffer.allocateDirect(size);
+ }
+ recording.stop();
+
+ List events = Events.fromRecording(recording);
+ Events.hasEvents(events);
+
+ long count = 0;
+ long totalCapacity = 0;
+ long memoryUsed = 0;
+
+ for (RecordedEvent event : events) {
+ System.out.println(event);
+ Asserts.assertTrue(Events.isEventType(event, EVENT_PATH), "Wrong event type");
+ count = Math.max(count, Events.assertField(event, "count").getValue());
+ totalCapacity = Math.max(totalCapacity, Events.assertField(event, "totalCapacity").getValue());
+ memoryUsed = Math.max(memoryUsed, Events.assertField(event, "memoryUsed").getValue());
+ Asserts.assertEquals(VM.maxDirectMemory(), Events.assertField(event, "maxCapacity").getValue());
+ }
+
+ Asserts.assertGreaterThanOrEqual(count, (long)rounds, "Too few count in statistics event");
+ Asserts.assertGreaterThanOrEqual(totalCapacity, (long)(rounds * size), "Too few totalCapacity in statistics event");
+ Asserts.assertGreaterThanOrEqual(memoryUsed, totalCapacity, "Too few memoryUsed in statistics event");
+ }
+ }
+}