mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
add JitSuppressor (disabled for now) to help with IDEA-207243 High CPU Usage while typing (<JIT Compiler> goes over 300%)
GitOrigin-RevId: 25ead0064d0405b564bdf212c586024db4e3da6a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8b3409b1d1
commit
c9fe57714a
+1
-1
@@ -33,7 +33,7 @@ class VmOptionsGenerator {
|
||||
'-Djdk.http.auth.tunneling.disabledSchemes=""',
|
||||
'-XX:+HeapDumpOnOutOfMemoryError',
|
||||
'-XX:-OmitStackTraceInFastThrow',
|
||||
'-Djdk.attach.allowAttachSelf',
|
||||
'-Djdk.attach.allowAttachSelf=true',
|
||||
]
|
||||
|
||||
static String computeVmOptions(JvmArchitecture arch, boolean isEAP, ProductProperties productProperties) {
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.application.impl;
|
||||
|
||||
import com.intellij.execution.process.OSProcessUtil;
|
||||
import com.intellij.ide.PowerSaveMode;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import sun.tools.attach.HotSpotVirtualMachine;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
// NOTE: compile with --add-exports jdk.attach/sun.tools.attach=ALL-UNNAMED in module-aware jdk
|
||||
public class JitSuppressor implements PowerSaveMode.Listener {
|
||||
private static final Logger LOG = Logger.getInstance(JitSuppressor.class);
|
||||
private static final String SELF_ATTACH_PROP = "jdk.attach.allowAttachSelf";
|
||||
private static final String EXCLUDE_ALL_FROM_C2_CLAUSE = "{ match : [\"*.*\"], c2 : { Exclude : true }}";
|
||||
// Limit C2 compilation with the given packages only. The package set was computed by test performance analysis:
|
||||
// it makes performance tests timing comparable with full C2 and same time IDE does not load CPU heavily with this limitation.
|
||||
private static final String[] C2_LIMIT_MASKS = {
|
||||
"com/intellij/openapi/application/*.*",
|
||||
"com/intellij/openapi/editor/*.*",
|
||||
"com/intellij/openapi/project/*.*",
|
||||
"com/intellij/openapi/util/text/*.*",
|
||||
"com/intellij/openapi/vfs/*.*",
|
||||
"com/intellij/openapi/fileTypes/*.*",
|
||||
"com/intellij/psi/codeStyle/*.*",
|
||||
"com/intellij/psi/util/*.*",
|
||||
"com/intellij/util/*.*",
|
||||
"java/lang/*.*",
|
||||
"java/math/*.*",
|
||||
"sun/*.*",
|
||||
};
|
||||
|
||||
public JitSuppressor() {
|
||||
if (!SystemProperties.getBooleanProperty("enable.jit.suppressor", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// java.specification.version has values "1.8", "1.7" e.t.c. for jdk <= 8 and "9", "10", "11", 12" for others
|
||||
if (System.getProperty("java.specification.version").contains(".")) return;
|
||||
|
||||
String javaSpecVendor = System.getProperty("java.vm.specification.vendor");
|
||||
if (!"Oracle Corporation".equals(javaSpecVendor)) {
|
||||
LOG.warn("JitSuppressor functionality is not supported on non-Oracle vm. This one is " + javaSpecVendor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!"true".equals(System.getProperty(SELF_ATTACH_PROP))) {
|
||||
String msg = "JitSuppressor wasn't registered. Please ensure the command line contains -D" + SELF_ATTACH_PROP + "=true";
|
||||
if (ApplicationInfoImpl.isInStressTest()) {
|
||||
LOG.warn(msg + " to get production-like performance");
|
||||
}
|
||||
else if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
LOG.warn(msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.info("JitSuppressor is active");
|
||||
|
||||
ApplicationManager.getApplication().getMessageBus().connect().subscribe(PowerSaveMode.TOPIC, this);
|
||||
|
||||
// call the handler to make initial setup
|
||||
powerSaveStateChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void powerSaveStateChanged() {
|
||||
String directives = generateDirectives();
|
||||
|
||||
Runnable runnable = () -> setDirectives(directives);
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
runnable.run();
|
||||
} else {
|
||||
ApplicationManager.getApplication().executeOnPooledThread(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setDirectives(String directives) {
|
||||
File tmpFile = null;
|
||||
try {
|
||||
tmpFile = FileUtil.createTempFile("c2_directive", "json");
|
||||
FileUtil.writeToFile(tmpFile, directives);
|
||||
|
||||
VirtualMachine vm = VirtualMachine.attach(OSProcessUtil.getApplicationPid());
|
||||
HotSpotVirtualMachine hvm = (HotSpotVirtualMachine)vm;
|
||||
hvm.executeJCmd("Compiler.directives_clear");
|
||||
hvm.executeJCmd("Compiler.directives_add " + tmpFile.getAbsolutePath());
|
||||
vm.detach();
|
||||
}
|
||||
catch (AttachNotSupportedException | IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
finally {
|
||||
if (tmpFile != null) {
|
||||
FileUtil.delete(tmpFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String generateDirectives() {
|
||||
String includes = PowerSaveMode.isEnabled()
|
||||
? ""
|
||||
: StringUtil.join(C2_LIMIT_MASKS, mask -> "{ match: [\"" + mask + "\"], c2: { Exclude: false, }, },", "");
|
||||
return "[" + includes + EXCLUDE_ALL_FROM_C2_CLAUSE + "]";
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,9 @@
|
||||
<component>
|
||||
<implementation-class>com.intellij.diagnostic.PerformanceWatcher</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>com.intellij.openapi.application.impl.JitSuppressor</implementation-class>
|
||||
</component>
|
||||
|
||||
<component>
|
||||
<interface-class>com.intellij.notification.NotificationsConfiguration</interface-class>
|
||||
|
||||
Reference in New Issue
Block a user