提交 44c71bc8 编写于 作者: D Denghui Dong 提交者: D-D-H

Revert "Revert "[JFR] add support for opto object allocations sampling""

This reverts commit 98c962d6.
上级 e31837fc
/*
* Copyright (c) 2019 Alibaba Group Holding Limited. 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. Alibaba 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.
*
*/
package jdk.jfr;
/**
* A constant class for JFR Event, contains the names of some events used by jdk.
*/
public class EventNames {
private final static String PREFIX = "jdk.";
public final static String OptoInstanceObjectAllocation = PREFIX + "OptoInstanceObjectAllocation";
public final static String OptoArrayObjectAllocation = PREFIX + "OptoArrayObjectAllocation";
}
...@@ -673,4 +673,7 @@ public final class Recording implements Closeable { ...@@ -673,4 +673,7 @@ public final class Recording implements Closeable {
internal.setSetting(id, value); internal.setSetting(id, value);
} }
public boolean isRecorderEnabled(String eventName) {
return internal.isRecorderEnabled(eventName);
}
} }
...@@ -629,6 +629,16 @@ ...@@ -629,6 +629,16 @@
<setting name="threshold">10 ms</setting> <setting name="threshold">10 ms</setting>
</event> </event>
<event name="jdk.OptoInstanceObjectAllocation">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
</event>
<event name="jdk.OptoArrayObjectAllocation">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
</event>
......
...@@ -629,6 +629,16 @@ ...@@ -629,6 +629,16 @@
<setting name="threshold">10 ms</setting> <setting name="threshold">10 ms</setting>
</event> </event>
<event name="jdk.OptoInstanceObjectAllocation">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
</event>
<event name="jdk.OptoArrayObjectAllocation">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
</event>
......
...@@ -100,4 +100,27 @@ public final class RecordedClass extends RecordedObject { ...@@ -100,4 +100,27 @@ public final class RecordedClass extends RecordedObject {
public long getId() { public long getId() {
return uniqueId; return uniqueId;
} }
/**
* Returns the object size for the class.
* <p>
* The object size for instance class is accurate. But for the array class, it
* is a magic code 0x1111baba. The array object size can not be determined statically
* from the JVM klass information because array object size is affected by
* actual element length.
*
* @return the object size (instance object), or magic code 0x1111baba (array object)
*/
public int getObjectSize() {
return getTyped("objectSize", Integer.class, -1);
}
/**
* Checks whether the class is for instance or array.
*
* @return true or false
*/
public boolean isArray() {
return getName().startsWith("[");
}
} }
...@@ -293,6 +293,20 @@ public final class JVM { ...@@ -293,6 +293,20 @@ public final class JVM {
*/ */
public native void setSampleThreads(boolean sampleThreads) throws IllegalStateException; public native void setSampleThreads(boolean sampleThreads) throws IllegalStateException;
/**
* Turn on/off objects allocations sampling.
*
* @param sampleAllocations true if object allocations should be sampled, false otherwise.
*/
public native void setSampleObjectAllocations(boolean sampleAllocations);
/**
* Set object allocations sampling interval.
*
* @param interval
*/
public native void setObjectAllocationsSamplingInterval(long interval) throws IllegalArgumentException;
/** /**
* Turn on/off compressed integers. * Turn on/off compressed integers.
* *
......
...@@ -49,6 +49,8 @@ public final class Options { ...@@ -49,6 +49,8 @@ public final class Options {
private static final boolean DEFAULT_SAMPLE_THREADS = true; private static final boolean DEFAULT_SAMPLE_THREADS = true;
private static final long DEFAULT_MAX_CHUNK_SIZE = 12 * 1024 * 1024; private static final long DEFAULT_MAX_CHUNK_SIZE = 12 * 1024 * 1024;
private static final SafePath DEFAULT_DUMP_PATH = SecuritySupport.USER_HOME; private static final SafePath DEFAULT_DUMP_PATH = SecuritySupport.USER_HOME;
private static final boolean DEFAULT_SAMPLE_OBJECT_ALLOCATIONS = false;
private static final long DEFAULT_OBJECT_ALLOCATIONS_SAMPLING_INTERVAL = 1024;
private static long memorySize; private static long memorySize;
private static long globalBufferSize; private static long globalBufferSize;
...@@ -58,6 +60,8 @@ public final class Options { ...@@ -58,6 +60,8 @@ public final class Options {
private static boolean sampleThreads; private static boolean sampleThreads;
private static long maxChunkSize; private static long maxChunkSize;
private static SafePath dumpPath; private static SafePath dumpPath;
private static boolean sampleObjectAllocations;
private static long objectAllocationsSamplingInterval;
static { static {
final long pageSize = Unsafe.getUnsafe().pageSize(); final long pageSize = Unsafe.getUnsafe().pageSize();
...@@ -139,6 +143,31 @@ public final class Options { ...@@ -139,6 +143,31 @@ public final class Options {
return sampleThreads; return sampleThreads;
} }
public static synchronized void setSampleObjectAllocations(Boolean sample) {
jvm.setSampleObjectAllocations(sample);
sampleObjectAllocations = sample;
}
public static synchronized boolean getSampleObjectAllocations() {
return sampleObjectAllocations;
}
/**
* Set interval of sampling object allocation events
* @param interval the number of newly created objects between two sampling
*/
public static synchronized void setObjectAllocationsSamplingInterval(Long interval) {
if (interval <= 0) {
throw new IllegalArgumentException("interval should be greater than 0");
}
jvm.setObjectAllocationsSamplingInterval(interval);
objectAllocationsSamplingInterval = interval;
}
public static synchronized long getObjectAllocationsSamplingInterval() {
return objectAllocationsSamplingInterval;
}
private static synchronized void reset() { private static synchronized void reset() {
setMaxChunkSize(DEFAULT_MAX_CHUNK_SIZE); setMaxChunkSize(DEFAULT_MAX_CHUNK_SIZE);
setMemorySize(DEFAULT_MEMORY_SIZE); setMemorySize(DEFAULT_MEMORY_SIZE);
...@@ -148,6 +177,8 @@ public final class Options { ...@@ -148,6 +177,8 @@ public final class Options {
setSampleThreads(DEFAULT_SAMPLE_THREADS); setSampleThreads(DEFAULT_SAMPLE_THREADS);
setStackDepth(DEFAULT_STACK_DEPTH); setStackDepth(DEFAULT_STACK_DEPTH);
setThreadBufferSize(DEFAULT_THREAD_BUFFER_SIZE); setThreadBufferSize(DEFAULT_THREAD_BUFFER_SIZE);
setSampleObjectAllocations(DEFAULT_SAMPLE_OBJECT_ALLOCATIONS);
setObjectAllocationsSamplingInterval(DEFAULT_OBJECT_ALLOCATIONS_SAMPLING_INTERVAL);
} }
static synchronized long getWaitInterval() { static synchronized long getWaitInterval() {
......
...@@ -47,6 +47,7 @@ import java.util.Timer; ...@@ -47,6 +47,7 @@ import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import jdk.jfr.EventNames;
import jdk.jfr.EventType; import jdk.jfr.EventType;
import jdk.jfr.FlightRecorder; import jdk.jfr.FlightRecorder;
import jdk.jfr.FlightRecorderListener; import jdk.jfr.FlightRecorderListener;
...@@ -551,4 +552,8 @@ public final class PlatformRecorder { ...@@ -551,4 +552,8 @@ public final class PlatformRecorder {
target.setStopTime(endTime); target.setStopTime(endTime);
target.setInternalDuration(Duration.between(startTime, endTime)); target.setInternalDuration(Duration.between(startTime, endTime));
} }
public boolean isEnabled(String eventName) {
return MetadataRepository.getInstance().isEnabled(eventName);
}
} }
...@@ -775,4 +775,8 @@ public final class PlatformRecording implements AutoCloseable { ...@@ -775,4 +775,8 @@ public final class PlatformRecording implements AutoCloseable {
public SafePath getDumpOnExitDirectory() { public SafePath getDumpOnExitDirectory() {
return this.dumpOnExitDirectory; return this.dumpOnExitDirectory;
} }
public boolean isRecorderEnabled(String eventName) {
return recorder.isEnabled(eventName);
}
} }
...@@ -43,6 +43,7 @@ final class DCmdConfigure extends AbstractDCmd { ...@@ -43,6 +43,7 @@ final class DCmdConfigure extends AbstractDCmd {
/** /**
* Execute JFR.configure. * Execute JFR.configure.
* *
* @param onVMStart if cmd is invoked at the moment when vm is started
* @param repositoryPath the path * @param repositoryPath the path
* @param dumpPath path to dump to on fatal error (oom) * @param dumpPath path to dump to on fatal error (oom)
* @param stackDepth depth of stack traces * @param stackDepth depth of stack traces
...@@ -51,6 +52,8 @@ final class DCmdConfigure extends AbstractDCmd { ...@@ -51,6 +52,8 @@ final class DCmdConfigure extends AbstractDCmd {
* @param threadBufferSize size of thread buffer for events * @param threadBufferSize size of thread buffer for events
* @param maxChunkSize threshold at which a new chunk is created in the disk repository * @param maxChunkSize threshold at which a new chunk is created in the disk repository
* @param sampleThreads if thread sampling should be enabled * @param sampleThreads if thread sampling should be enabled
* @param sampleObjectAllocations if object allocations sampling should be enbaled
* @param objectAllocationsSamplingInterval interval of object allocations samplings
* *
* @return result * @return result
...@@ -59,6 +62,7 @@ final class DCmdConfigure extends AbstractDCmd { ...@@ -59,6 +62,7 @@ final class DCmdConfigure extends AbstractDCmd {
*/ */
public String execute public String execute
( (
Boolean onVMStart,
String repositoryPath, String repositoryPath,
String dumpPath, String dumpPath,
Integer stackDepth, Integer stackDepth,
...@@ -67,8 +71,9 @@ final class DCmdConfigure extends AbstractDCmd { ...@@ -67,8 +71,9 @@ final class DCmdConfigure extends AbstractDCmd {
Long threadBufferSize, Long threadBufferSize,
Long memorySize, Long memorySize,
Long maxChunkSize, Long maxChunkSize,
Boolean sampleThreads Boolean sampleThreads,
Boolean sampleObjectAllocations,
Long objectAllocationsSamplingInterval
) throws DCmdException { ) throws DCmdException {
if (Logger.shouldLog(LogTag.JFR_DCMD, LogLevel.DEBUG)) { if (Logger.shouldLog(LogTag.JFR_DCMD, LogLevel.DEBUG)) {
Logger.log(LogTag.JFR_DCMD, LogLevel.DEBUG, "Executing DCmdConfigure: repositorypath=" + repositoryPath + Logger.log(LogTag.JFR_DCMD, LogLevel.DEBUG, "Executing DCmdConfigure: repositorypath=" + repositoryPath +
...@@ -82,6 +87,13 @@ final class DCmdConfigure extends AbstractDCmd { ...@@ -82,6 +87,13 @@ final class DCmdConfigure extends AbstractDCmd {
", samplethreads" + sampleThreads); ", samplethreads" + sampleThreads);
} }
// Check parameters correctness
if (!onVMStart) {
if (sampleObjectAllocations != null || objectAllocationsSamplingInterval != null) {
Logger.log(LogTag.JFR, LogLevel.ERROR, "Could not change sampleObjectAllocations and objectAllocationsSamplingInterval during application's running");
return getResult();
}
}
boolean updated = false; boolean updated = false;
if (repositoryPath != null) { if (repositoryPath != null) {
...@@ -152,6 +164,20 @@ final class DCmdConfigure extends AbstractDCmd { ...@@ -152,6 +164,20 @@ final class DCmdConfigure extends AbstractDCmd {
updated = true; updated = true;
} }
if (objectAllocationsSamplingInterval != null) {
Options.setObjectAllocationsSamplingInterval(objectAllocationsSamplingInterval);
Logger.log(LogTag.JFR, LogLevel.INFO, "object allocations sampling interval set to " + objectAllocationsSamplingInterval);
printObjectAllocationsSamplingInterval();
updated = true;
}
if (sampleObjectAllocations != null) {
Options.setSampleObjectAllocations(sampleObjectAllocations);
Logger.log(LogTag.JFR, LogLevel.INFO, "Sample object allocations set to " + sampleObjectAllocations);
printSampleObjectAllocations();
updated = true;
}
if (!updated) { if (!updated) {
println("Current configuration:"); println("Current configuration:");
println(); println();
...@@ -163,6 +189,8 @@ final class DCmdConfigure extends AbstractDCmd { ...@@ -163,6 +189,8 @@ final class DCmdConfigure extends AbstractDCmd {
printMemorySize(); printMemorySize();
printMaxChunkSize(); printMaxChunkSize();
printSampleThreads(); printSampleThreads();
printSampleObjectAllocations();
printObjectAllocationsSamplingInterval();
} }
return getResult(); return getResult();
} }
...@@ -214,4 +242,12 @@ final class DCmdConfigure extends AbstractDCmd { ...@@ -214,4 +242,12 @@ final class DCmdConfigure extends AbstractDCmd {
printBytes(Options.getMaxChunkSize()); printBytes(Options.getMaxChunkSize());
println(); println();
} }
private void printSampleObjectAllocations() {
println("Sample object allocations: " + Options.getSampleObjectAllocations());
}
private void printObjectAllocationsSamplingInterval() {
println("objects allocations sampling interval: " + Options.getObjectAllocationsSamplingInterval());
}
} }
...@@ -36,12 +36,14 @@ import java.util.Arrays; ...@@ -36,12 +36,14 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import jdk.jfr.EventNames;
import jdk.jfr.FlightRecorder; import jdk.jfr.FlightRecorder;
import jdk.jfr.Recording; import jdk.jfr.Recording;
import jdk.jfr.internal.JVM; import jdk.jfr.internal.JVM;
import jdk.jfr.internal.LogLevel; import jdk.jfr.internal.LogLevel;
import jdk.jfr.internal.LogTag; import jdk.jfr.internal.LogTag;
import jdk.jfr.internal.Logger; import jdk.jfr.internal.Logger;
import jdk.jfr.internal.Options;
import jdk.jfr.internal.OldObjectSample; import jdk.jfr.internal.OldObjectSample;
import jdk.jfr.internal.PrivateAccess; import jdk.jfr.internal.PrivateAccess;
import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.SecuritySupport.SafePath;
...@@ -116,7 +118,7 @@ final class DCmdStart extends AbstractDCmd { ...@@ -116,7 +118,7 @@ final class DCmdStart extends AbstractDCmd {
} catch(FileNotFoundException e) { } catch(FileNotFoundException e) {
throw new DCmdException("Could not find settings file'" + configName + "'", e); throw new DCmdException("Could not find settings file'" + configName + "'", e);
} catch (IOException | ParseException e) { } catch (IOException | ParseException e) {
throw new DCmdException("Could not parse settings file '" + settings[0] + "'", e); throw new DCmdException("Could not parse settings file '" + configName + "'", e);
} }
} }
...@@ -151,6 +153,14 @@ final class DCmdStart extends AbstractDCmd { ...@@ -151,6 +153,14 @@ final class DCmdStart extends AbstractDCmd {
recording.setSettings(s); recording.setSettings(s);
SafePath safePath = null; SafePath safePath = null;
if (recording.isRecorderEnabled(EventNames.OptoInstanceObjectAllocation) ||
recording.isRecorderEnabled(EventNames.OptoArrayObjectAllocation)) {
if (!Options.getSampleObjectAllocations()) {
println("Please add -XX:FlightRecorderOptions=sampleobjectallocations=true in JVM options.");
return getResult();
}
}
if (path != null) { if (path != null) {
try { try {
if (dumpOnExit == null) { if (dumpOnExit == null) {
......
/*
* Copyright (c) 2019 Alibaba Group Holding Limited. 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. Alibaba 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.
*
*/
package jfr.event.objectsprofiling;
import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.TimeUnit;
import jdk.jfr.Recording;
import jdk.jfr.consumer.RecordedEvent;
import jdk.jfr.consumer.RecordedClass;
import jdk.jfr.consumer.RecordedStackTrace;
import jdk.jfr.consumer.RecordedFrame;
import sun.hotspot.WhiteBox;
import jdk.test.lib.Asserts;
import jdk.test.lib.jfr.EventNames;
import jdk.test.lib.jfr.Events;
import jdk.test.lib.Utils;
/*
* @test TestOptoObjectAllocationsSampling
* @library /lib /
*
* @build sun.hotspot.WhiteBox
* @build ClassFileInstaller
*
* @compile -g TestOptoObjectAllocationsSampling.java
*
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
*
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation
* -XX:+LogJFR -XX:FlightRecorderOptions=sampleobjectallocations=true,objectallocationssamplinginterval=1
* jfr.event.objectsprofiling.TestOptoObjectAllocationsSampling
*/
public class TestOptoObjectAllocationsSampling {
private static final WhiteBox WB;
private static final Method OPTO_METHOD;
private static final int OPTO_METHOD_INVOKE_COUNT = 10;
private static final String OPTO_METHOD_NAME = "fireOptoAllocations";
private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
private static final int RECORDED_ARRAY_CLASS_OBJECT_SIZE_MAGIC_CODE = 0x1111baba;
static {
try {
WB = WhiteBox.getWhiteBox();
Class<?> thisClass = TestOptoObjectAllocationsSampling.class;
OPTO_METHOD = thisClass.getMethod(OPTO_METHOD_NAME, Integer.TYPE, Byte.TYPE);
} catch (Exception e) {
Asserts.fail(e.getMessage());
throw new ExceptionInInitializerError(e);
}
}
private static class InstanceObject {
private byte content;
InstanceObject(byte content) {
this.content = content;
}
public String toString() {
return "InstanceObject ( " + content + " )";
}
}
public static Object array;
public static Object instance;
public static void fireOptoAllocations(int arrayLength, byte b) {
array = new InstanceObject[arrayLength];
instance = new InstanceObject(b);
}
private static void ensureOptoMethod() throws Exception {
int initialCompLevel = WB.getMethodCompilationLevel(OPTO_METHOD);
if (initialCompLevel != COMP_LEVEL_FULL_OPTIMIZATION) {
WB.enqueueMethodForCompilation(OPTO_METHOD, COMP_LEVEL_FULL_OPTIMIZATION);
}
Utils.waitForCondition(() -> COMP_LEVEL_FULL_OPTIMIZATION == WB.getMethodCompilationLevel(OPTO_METHOD), 30_000L);
System.out.format("%s is already compiled at full optimization compile level\n", OPTO_METHOD_NAME);
}
private static void assertOptoMethod() throws Exception {
int compLevel = WB.getMethodCompilationLevel(OPTO_METHOD);
Asserts.assertTrue(compLevel == COMP_LEVEL_FULL_OPTIMIZATION);
}
private static void runForLong(int arg1, byte arg2) {
for (int i = 0; i < 1000_000; i++) {
try {
ensureOptoMethod();
fireOptoAllocations(arg1, arg2);
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {
}
}
}
public static void main(String[] args) throws Exception {
int arg1 = 3*1024;
byte arg2 = (byte)0x66;
// Run warm code to prevent deoptimizaiton.
// It will deoptimize if it runs without this warmup step.
fireOptoAllocations(arg1, arg2);
ensureOptoMethod();
assertOptoMethod();
// runForLong(arg1, arg2);
try (Recording recording = new Recording()) {
recording.enable(EventNames.OptoArrayObjectAllocation);
recording.enable(EventNames.OptoInstanceObjectAllocation);
recording.start();
// fireOptoAllocationsMethod would be deoptimized after jfr recording is started.
// The root cause is not clear.
// Invoke ensureOptoMethod blindly to enforce it in level 4 again.
ensureOptoMethod();
for (int i = 0; i < OPTO_METHOD_INVOKE_COUNT; i++) {
assertOptoMethod();
fireOptoAllocations(arg1, arg2);
WB.youngGC();
}
recording.stop();
List<RecordedEvent> events = Events.fromRecording(recording);
int countOfInstanceObject = 0;
int countOfArrayObject = 0;
final String instanceObjectClassName = InstanceObject.class.getName();
final String arrayObjectClassName = InstanceObject[].class.getName();
for (RecordedEvent event : events) {
RecordedStackTrace stackTrace = event.getStackTrace();
Asserts.assertTrue(stackTrace != null);
List<RecordedFrame> frames = stackTrace.getFrames();
Asserts.assertTrue(frames != null && frames.size() > 0);
RecordedFrame topFrame = frames.get(0);
Asserts.assertTrue(event.hasField("objectClass"));
RecordedClass clazz = event.getValue("objectClass");
String className = clazz.getName();
Asserts.assertTrue(event.getStackTrace().getFrames().size() > 0);
int objectSize = clazz.getObjectSize();
System.out.format("Allocation Object Class Name: %s, Object Size: %x, topFrame: %s\n", className, objectSize, topFrame.getMethod());
if (className.equals(instanceObjectClassName)) {
Asserts.assertTrue(!clazz.isArray());
Asserts.assertTrue(objectSize > 0);
Asserts.assertTrue(topFrame.getLineNumber() > 0);
Asserts.assertTrue(topFrame.getBytecodeIndex() > 0);
countOfInstanceObject++;
} else if (className.equals(arrayObjectClassName)) {
Asserts.assertTrue(clazz.isArray());
Asserts.assertTrue(objectSize == RECORDED_ARRAY_CLASS_OBJECT_SIZE_MAGIC_CODE);
countOfArrayObject++;
Asserts.assertTrue(topFrame.getLineNumber() > 0);
Asserts.assertTrue(topFrame.getBytecodeIndex() > 0);
}
}
System.out.format("Total Event Count: %d, EventOptoInstanceObjectAllocaiton Count: %d, EventOptoArrayObjectAllocation Count: %d\n", events.size(), countOfInstanceObject, countOfArrayObject);
Asserts.assertTrue(countOfArrayObject == countOfInstanceObject);
Asserts.assertTrue(countOfArrayObject == OPTO_METHOD_INVOKE_COUNT);
Asserts.assertTrue(events.size() >= (countOfInstanceObject + countOfArrayObject));
}
}
}
...@@ -176,6 +176,9 @@ public class EventNames { ...@@ -176,6 +176,9 @@ public class EventNames {
public final static String ActiveRecording = PREFIX + "ActiveRecording"; public final static String ActiveRecording = PREFIX + "ActiveRecording";
public final static String ActiveSetting = PREFIX + "ActiveSetting"; public final static String ActiveSetting = PREFIX + "ActiveSetting";
public final static String OptoInstanceObjectAllocation = PREFIX + "OptoInstanceObjectAllocation";
public final static String OptoArrayObjectAllocation = PREFIX + "OptoArrayObjectAllocation";
public static boolean isGcEvent(EventType et) { public static boolean isGcEvent(EventType et) {
return et.getCategoryNames().contains(GC_CATEGORY); return et.getCategoryNames().contains(GC_CATEGORY);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册