mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
[performance] IJPL-173892 FUS: add project count, oom error flag and last action to low.memory events
(cherry picked from commit 048a9136700b3d9741cd21cb74260e9a8e62a16b) IJ-CR-151911 GitOrigin-RevId: d0a323177357b21ec1a0db98ab699c6a4fb5eb15
This commit is contained in:
committed by
intellij-monorepo-bot
parent
2584933ede
commit
c388c9cc0e
@@ -71,7 +71,7 @@ public final class DefaultIdeaErrorLogger {
|
||||
var kind = getOOMErrorKind(event.getThrowable());
|
||||
if (kind != null) {
|
||||
ourOomOccurred = true;
|
||||
LowMemoryNotifier.showNotification(kind, true, true);
|
||||
LowMemoryNotifier.showNotification(kind, true);
|
||||
}
|
||||
else if (!ourOomOccurred) {
|
||||
MessagePool.getInstance().addIdeFatalMessage(event);
|
||||
|
||||
@@ -4,6 +4,8 @@ package com.intellij.diagnostic
|
||||
import com.intellij.diagnostic.VMOptions.MemoryKind
|
||||
import com.intellij.diagnostic.opentelemetry.SafepointBean
|
||||
import com.intellij.ide.PowerSaveMode
|
||||
import com.intellij.idea.IdeaLogger
|
||||
import com.intellij.internal.statistic.collectors.fus.actions.persistence.ActionsEventLogGroup
|
||||
import com.intellij.internal.statistic.eventLog.EventLogGroup
|
||||
import com.intellij.internal.statistic.eventLog.events.*
|
||||
import com.intellij.internal.statistic.eventLog.events.EventFields.Boolean
|
||||
@@ -124,7 +126,7 @@ private class IdeHeartbeatEventReporterService(cs: CoroutineScope) {
|
||||
}
|
||||
|
||||
internal object UILatencyLogger : CounterUsagesCollector() {
|
||||
private val GROUP = EventLogGroup("performance", 74)
|
||||
private val GROUP = EventLogGroup("performance", 75)
|
||||
|
||||
internal val SYSTEM_CPU_LOAD: IntEventField = Int("system_cpu_load")
|
||||
internal val SWAP_LOAD: IntEventField = Int("swap_load")
|
||||
@@ -172,10 +174,22 @@ internal object UILatencyLogger : CounterUsagesCollector() {
|
||||
@JvmField
|
||||
val MAIN_MENU_LATENCY: EventId1<Long> = GROUP.registerEvent("mainmenu.latency", EventFields.DurationMs)
|
||||
|
||||
private val MEMORY_TYPE_FIELD = Enum("type", MemoryKind::class.java)
|
||||
private val HEAP_SIZE_FIELD = Int("heap_size_gigabytes")
|
||||
private val PROJECT_COUNT_FIELD = Int("project_count")
|
||||
private val IS_OOM_HAPPENED_FIELD = Boolean("oom_error")
|
||||
private val IS_FROM_CRASH_FIELD = Boolean("oom_crash")
|
||||
private val LAST_ACTION_FIELD = ActionsEventLogGroup.ActionIdField("last_action_id")
|
||||
|
||||
@JvmField
|
||||
val LOW_MEMORY_CONDITION: EventId2<MemoryKind, Int> = GROUP.registerEvent("low.memory",
|
||||
Enum("type", MemoryKind::class.java),
|
||||
Int("heap_size_gigabytes"))
|
||||
val LOW_MEMORY_CONDITION: VarargEventId = GROUP.registerVarargEvent("low.memory",
|
||||
MEMORY_TYPE_FIELD,
|
||||
HEAP_SIZE_FIELD,
|
||||
PROJECT_COUNT_FIELD,
|
||||
IS_OOM_HAPPENED_FIELD,
|
||||
IS_FROM_CRASH_FIELD,
|
||||
LAST_ACTION_FIELD,
|
||||
EventFields.Dumb)
|
||||
|
||||
// ==== JVMResponsivenessMonitor: overall system run-time-variability sampling
|
||||
|
||||
@@ -217,7 +231,22 @@ internal object UILatencyLogger : CounterUsagesCollector() {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun lowMemory(kind: MemoryKind, currentXmxMegabytes: Int) {
|
||||
LOW_MEMORY_CONDITION.log(kind, (currentXmxMegabytes.toDouble() / 1024).roundToInt())
|
||||
fun lowMemory(
|
||||
kind: MemoryKind,
|
||||
currentXmxMegabytes: Int,
|
||||
projectCount: Int,
|
||||
oomError: Boolean,
|
||||
fromCrashReport: Boolean,
|
||||
dumbMode: Boolean,
|
||||
) {
|
||||
LOW_MEMORY_CONDITION.log(
|
||||
MEMORY_TYPE_FIELD.with(kind),
|
||||
HEAP_SIZE_FIELD.with((currentXmxMegabytes.toDouble() / 1024).roundToInt()),
|
||||
PROJECT_COUNT_FIELD.with(projectCount),
|
||||
IS_OOM_HAPPENED_FIELD.with(oomError),
|
||||
IS_FROM_CRASH_FIELD.with(fromCrashReport),
|
||||
LAST_ACTION_FIELD.with(IdeaLogger.ourLastActionId),
|
||||
EventFields.Dumb.with(dumbMode)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,11 @@ import com.intellij.notification.NotificationAction;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.Notifications;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.util.LowMemoryWatcher;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
@@ -21,24 +25,35 @@ final class LowMemoryNotifier implements Disposable {
|
||||
private static final Set<VMOptions.MemoryKind> ourNotifications = ConcurrentCollectionFactory.createConcurrentSet();
|
||||
|
||||
private final LowMemoryWatcher myWatcher =
|
||||
LowMemoryWatcher.register(() -> showNotification(VMOptions.MemoryKind.HEAP, false, true), ONLY_AFTER_GC);
|
||||
LowMemoryWatcher.register(() -> showNotification(VMOptions.MemoryKind.HEAP, false), ONLY_AFTER_GC);
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
myWatcher.stop();
|
||||
}
|
||||
|
||||
static void showNotification(@NotNull VMOptions.MemoryKind kind, boolean error, boolean suggestAnalyzing) {
|
||||
static void showNotificationFromCrashAnalysis() {
|
||||
showNotification(VMOptions.MemoryKind.HEAP, true, true);
|
||||
}
|
||||
|
||||
static void showNotification(@NotNull VMOptions.MemoryKind kind, boolean oomError) {
|
||||
showNotification(kind, oomError, false);
|
||||
}
|
||||
|
||||
private static void showNotification(@NotNull VMOptions.MemoryKind kind, boolean oomError, boolean fromCrashReport) {
|
||||
if (!ourNotifications.add(kind)) return;
|
||||
|
||||
int currentXmx = VMOptions.readOption(VMOptions.MemoryKind.HEAP, true);
|
||||
UILatencyLogger.lowMemory(kind, currentXmx);
|
||||
Project[] projects = ProjectManager.getInstance().getOpenProjects();
|
||||
int projectCount = projects.length;
|
||||
boolean isDumb = ContainerUtil.exists(projects, p -> DumbService.isDumb(p));
|
||||
UILatencyLogger.lowMemory(kind, currentXmx, projectCount, oomError, fromCrashReport, isDumb);
|
||||
|
||||
var message = error ? IdeBundle.message("low.memory.notification.error", kind.label()) : IdeBundle.message("low.memory.notification.warning");
|
||||
var type = error ? NotificationType.ERROR : NotificationType.WARNING;
|
||||
var message = oomError ? IdeBundle.message("low.memory.notification.error", kind.label()) : IdeBundle.message("low.memory.notification.warning");
|
||||
var type = oomError ? NotificationType.ERROR : NotificationType.WARNING;
|
||||
var notification = new Notification("Low Memory", IdeBundle.message("low.memory.notification.title"), message, type);
|
||||
|
||||
if (suggestAnalyzing) {
|
||||
if (!fromCrashReport) {
|
||||
notification.addAction(NotificationAction.createSimpleExpiring(IdeBundle.message("low.memory.notification.analyze.action"), () ->
|
||||
new HeapDumpSnapshotRunnable(MemoryReportReason.UserInvoked,
|
||||
HeapDumpSnapshotRunnable.AnalysisOption.SCHEDULE_ON_NEXT_START).run()));
|
||||
|
||||
@@ -531,7 +531,7 @@ private suspend fun reportCrashesIfAny() {
|
||||
if (crashInfo.extraJvmLog != null) {
|
||||
// Detect crashes caused by OOME
|
||||
if (crashInfo.extraJvmLog.contains("java.lang.OutOfMemoryError: Java heap space")) {
|
||||
LowMemoryNotifier.showNotification(VMOptions.MemoryKind.HEAP, true, false)
|
||||
LowMemoryNotifier.showNotificationFromCrashAnalysis()
|
||||
}
|
||||
attachments += Attachment("jbr_err.txt", crashInfo.extraJvmLog).also { it.isIncluded = true }
|
||||
}
|
||||
|
||||
@@ -127,4 +127,7 @@ object ActionsEventLogGroup : CounterUsagesCollector() {
|
||||
"custom.action.invoked",
|
||||
ACTION_ID,
|
||||
EventFields.InputEvent)
|
||||
|
||||
@Suppress("FunctionName")
|
||||
internal fun ActionIdField(name: String): PrimitiveEventField<String?> = ActionIdEventField(name)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user