提交 b31dfb75 编写于 作者: E egahlin

8207829: FlightRecorderMXBeanImpl is leaking the first classloader which calls it

Reviewed-by: mgronlun
上级 64211239
...@@ -34,6 +34,8 @@ import java.util.List; ...@@ -34,6 +34,8 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Predicate; import java.util.function.Predicate;
import jdk.jfr.Event;
import jdk.jfr.EventType;
public final class RequestEngine { public final class RequestEngine {
...@@ -60,7 +62,11 @@ public final class RequestEngine { ...@@ -60,7 +62,11 @@ public final class RequestEngine {
private void execute() { private void execute() {
try { try {
if (accessControllerContext == null) { // native if (accessControllerContext == null) { // native
if (type.isJDK()) {
hook.run();
} else {
jvm.emitEvent(type.getId(), JVM.counterTime(), 0); jvm.emitEvent(type.getId(), JVM.counterTime(), 0);
}
Logger.log(LogTag.JFR_SYSTEM_EVENT, LogLevel.DEBUG, ()-> "Executed periodic hook for " + type.getLogName()); Logger.log(LogTag.JFR_SYSTEM_EVENT, LogLevel.DEBUG, ()-> "Executed periodic hook for " + type.getLogName());
} else { } else {
executeSecure(); executeSecure();
...@@ -91,11 +97,12 @@ public final class RequestEngine { ...@@ -91,11 +97,12 @@ public final class RequestEngine {
private final static List<RequestHook> entries = new CopyOnWriteArrayList<>(); private final static List<RequestHook> entries = new CopyOnWriteArrayList<>();
private static long lastTimeMillis; private static long lastTimeMillis;
// Insertion takes O(2*n), could be O(1) with HashMap, but
// thinking is that CopyOnWriteArrayList is faster
// to iterate over, which will happen more over time.
public static void addHook(AccessControlContext acc, PlatformEventType type, Runnable hook) { public static void addHook(AccessControlContext acc, PlatformEventType type, Runnable hook) {
Objects.requireNonNull(acc); Objects.requireNonNull(acc);
addHookInternal(acc, type, hook);
}
private static void addHookInternal(AccessControlContext acc, PlatformEventType type, Runnable hook) {
RequestHook he = new RequestHook(acc, type, hook); RequestHook he = new RequestHook(acc, type, hook);
for (RequestHook e : entries) { for (RequestHook e : entries) {
if (e.hook == hook) { if (e.hook == hook) {
...@@ -103,10 +110,24 @@ public final class RequestEngine { ...@@ -103,10 +110,24 @@ public final class RequestEngine {
} }
} }
he.type.setEventHook(true); he.type.setEventHook(true);
// Insertion takes O(2*n), could be O(1) with HashMap, but
// thinking is that CopyOnWriteArrayList is faster
// to iterate over, which will happen more over time.
entries.add(he); entries.add(he);
logHook("Added", type); logHook("Added", type);
} }
public static void addTrustedJDKHook(Class<? extends Event> eventClass, Runnable runnable) {
if (eventClass.getClassLoader() != null) {
throw new SecurityException("Hook can only be registered for event classes that are loaded by the bootstrap class loader");
}
if (runnable.getClass().getClassLoader() != null) {
throw new SecurityException("Runnable hook class must be loaded by the bootstrap class loader");
}
EventType eType = MetadataRepository.getInstance().getEventType(eventClass);
PlatformEventType pType = PrivateAccess.getInstance().getPlatformEventType(eType);
addHookInternal(null, pType, runnable);
}
private static void logHook(String action, PlatformEventType type) { private static void logHook(String action, PlatformEventType type) {
if (type.isJDK() || type.isJVM()) { if (type.isJDK() || type.isJVM()) {
......
...@@ -29,7 +29,6 @@ import java.util.ArrayList; ...@@ -29,7 +29,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import jdk.jfr.Event; import jdk.jfr.Event;
import jdk.jfr.FlightRecorder;
import jdk.jfr.events.ActiveRecordingEvent; import jdk.jfr.events.ActiveRecordingEvent;
import jdk.jfr.events.ActiveSettingEvent; import jdk.jfr.events.ActiveSettingEvent;
import jdk.jfr.events.ErrorThrownEvent; import jdk.jfr.events.ErrorThrownEvent;
...@@ -46,7 +45,6 @@ import jdk.jfr.internal.LogTag; ...@@ -46,7 +45,6 @@ import jdk.jfr.internal.LogTag;
import jdk.jfr.internal.Logger; import jdk.jfr.internal.Logger;
import jdk.jfr.internal.RequestEngine; import jdk.jfr.internal.RequestEngine;
import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.SecuritySupport;
import jdk.jfr.internal.Utils;
public final class JDKEvents { public final class JDKEvents {
...@@ -87,7 +85,7 @@ public final class JDKEvents { ...@@ -87,7 +85,7 @@ public final class JDKEvents {
SecuritySupport.registerEvent((Class<? extends Event>) eventClass); SecuritySupport.registerEvent((Class<? extends Event>) eventClass);
} }
initializationTriggered = true; initializationTriggered = true;
FlightRecorder.addPeriodicEvent(ExceptionStatisticsEvent.class, emitExceptionStatistics); RequestEngine.addTrustedJDKHook(ExceptionStatisticsEvent.class, emitExceptionStatistics);
} }
} catch (Exception e) { } catch (Exception e) {
Logger.log(LogTag.JFR_SYSTEM, LogLevel.WARN, "Could not initialize JDK events. " + e.getMessage()); Logger.log(LogTag.JFR_SYSTEM, LogLevel.WARN, "Could not initialize JDK events. " + e.getMessage());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册