mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[memory-agent] Add retained sizes into for objects in instances tree if memory agent enabled
This commit is contained in:
@@ -4,19 +4,26 @@ package com.intellij.debugger.memory.agent;
|
||||
import com.intellij.debugger.engine.DebugProcessAdapterImpl;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.SuspendContextImpl;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
||||
import com.intellij.debugger.memory.agent.extractor.AgentExtractor;
|
||||
import com.intellij.debugger.memory.ui.JavaReferenceInfo;
|
||||
import com.intellij.debugger.memory.ui.SizedReferenceInfo;
|
||||
import com.intellij.execution.JavaExecutionUtil;
|
||||
import com.intellij.execution.configurations.JavaParameters;
|
||||
import com.intellij.execution.configurations.ParametersList;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import one.util.streamex.IntStreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
@@ -64,6 +71,23 @@ public class MemoryAgentUtil {
|
||||
parametersList.add("-agentpath:" + path);
|
||||
}
|
||||
|
||||
public static List<JavaReferenceInfo> tryCalculateSizes(@NotNull List<JavaReferenceInfo> objects, @Nullable MemoryAgent agent) {
|
||||
if (agent == null || !agent.canEvaluateObjectsSizes()) return objects;
|
||||
try {
|
||||
long[] sizes = agent.evaluateObjectsSizes(ContainerUtil.map(objects, x -> x.getObjectReference()));
|
||||
return IntStreamEx.range(0, objects.size())
|
||||
.mapToObj(i -> new SizedReferenceInfo(objects.get(i).getObjectReference(), sizes[i]))
|
||||
.reverseSorted(Comparator.comparing(x -> x.size()))
|
||||
.map(x -> (JavaReferenceInfo)x)
|
||||
.toList();
|
||||
}
|
||||
catch (EvaluateException e) {
|
||||
LOG.error("Could not estimate objects sizes");
|
||||
}
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
public static void loadAgentProxy(@NotNull DebugProcessImpl debugProcess, @NotNull Consumer<MemoryAgent> agentLoaded) {
|
||||
debugProcess.addDebugProcessListener(new DebugProcessAdapterImpl() {
|
||||
@Override
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
package com.intellij.debugger.memory.filtering;
|
||||
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.memory.ui.JavaReferenceInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.xdebugger.XExpression;
|
||||
import com.sun.jdi.Value;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -54,18 +54,18 @@ public class FilteringTask implements Runnable {
|
||||
myCallback.started(myValues.size());
|
||||
int proceedCount;
|
||||
for (proceedCount = 0; proceedCount < myValues.size() && !myIsCancelled; proceedCount++) {
|
||||
Value value = myValues.get(proceedCount);
|
||||
CheckingResult result = myChecker.check(value);
|
||||
JavaReferenceInfo info = myValues.get(proceedCount);
|
||||
CheckingResult result = myChecker.check(info.getObjectReference());
|
||||
FilteringTaskCallback.Action action = FilteringTaskCallback.Action.CONTINUE;
|
||||
switch (result.getResult()) {
|
||||
case MATCH:
|
||||
action = myCallback.matched(value);
|
||||
action = myCallback.matched(info);
|
||||
break;
|
||||
case NO_MATCH:
|
||||
action = myCallback.notMatched(value);
|
||||
action = myCallback.notMatched(info);
|
||||
break;
|
||||
case ERROR:
|
||||
action = myCallback.error(value, result.getFailureDescription());
|
||||
action = myCallback.error(info, result.getFailureDescription());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ public class FilteringTask implements Runnable {
|
||||
|
||||
public interface ValuesList {
|
||||
int size();
|
||||
Value get(int index);
|
||||
|
||||
JavaReferenceInfo get(int index);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.intellij.debugger.memory.filtering;
|
||||
|
||||
import com.sun.jdi.Value;
|
||||
import com.intellij.debugger.memory.ui.JavaReferenceInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -25,13 +25,13 @@ public interface FilteringTaskCallback {
|
||||
void started(int totalCount);
|
||||
|
||||
@NotNull
|
||||
Action matched(@NotNull Value ref);
|
||||
Action matched(@NotNull JavaReferenceInfo ref);
|
||||
|
||||
@NotNull
|
||||
Action notMatched(@NotNull Value ref);
|
||||
Action notMatched(@NotNull JavaReferenceInfo ref);
|
||||
|
||||
@NotNull
|
||||
Action error(@NotNull Value ref, @NotNull String description);
|
||||
Action error(@NotNull JavaReferenceInfo ref, @NotNull String description);
|
||||
|
||||
void completed(@NotNull FilteringResult reason);
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@ import com.intellij.debugger.engine.SuspendContextImpl;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContext;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
|
||||
import com.intellij.debugger.memory.agent.MemoryAgentUtil;
|
||||
import com.intellij.debugger.memory.filtering.FilteringResult;
|
||||
import com.intellij.debugger.memory.filtering.FilteringTask;
|
||||
import com.intellij.debugger.memory.filtering.FilteringTaskCallback;
|
||||
import com.intellij.debugger.memory.utils.AndroidUtil;
|
||||
import com.intellij.debugger.memory.utils.ErrorsValueGroup;
|
||||
import com.intellij.debugger.memory.utils.InstanceJavaValue;
|
||||
import com.intellij.debugger.memory.utils.InstanceValueDescriptor;
|
||||
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.MessageDescriptor;
|
||||
import com.intellij.debugger.ui.impl.watch.NodeManagerImpl;
|
||||
@@ -41,8 +41,6 @@ import com.intellij.xdebugger.impl.ui.XDebuggerExpressionEditor;
|
||||
import com.intellij.xdebugger.memory.ui.InstancesTree;
|
||||
import com.intellij.xdebugger.memory.ui.InstancesViewBase;
|
||||
import com.intellij.xdebugger.memory.utils.InstancesProvider;
|
||||
import com.sun.jdi.ObjectReference;
|
||||
import com.sun.jdi.Value;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -184,8 +182,8 @@ class InstancesView extends InstancesViewBase {
|
||||
final int limit = myIsAndroidVM
|
||||
? AndroidUtil.ANDROID_INSTANCES_LIMIT
|
||||
: DEFAULT_INSTANCES_LIMIT;
|
||||
List<ObjectReference> instances = ContainerUtil
|
||||
.map(getInstancesProvider().getInstances(limit + 1), referenceInfo -> ((JavaReferenceInfo)referenceInfo).getObjectReference());
|
||||
List<JavaReferenceInfo> instances = ContainerUtil
|
||||
.map(getInstancesProvider().getInstances(limit + 1), referenceInfo -> ((JavaReferenceInfo)referenceInfo));
|
||||
|
||||
final EvaluationContextImpl evaluationContext = myDebugProcess
|
||||
.getDebuggerContext().createEvaluationContext();
|
||||
@@ -195,9 +193,11 @@ class InstancesView extends InstancesViewBase {
|
||||
instances = instances.subList(0, limit);
|
||||
}
|
||||
|
||||
instances = MemoryAgentUtil.tryCalculateSizes(instances, myDebugProcess.getMemoryAgent());
|
||||
|
||||
if (evaluationContext != null) {
|
||||
synchronized (myFilteringTaskLock) {
|
||||
List<ObjectReference> finalInstances = instances;
|
||||
List<JavaReferenceInfo> finalInstances = instances;
|
||||
ApplicationManager.getApplication().runReadAction(() -> {
|
||||
myFilteringTask = new MyFilteringWorker(finalInstances, myFilterConditionEditor.getExpression(), evaluationContext);
|
||||
myFilteringTask.execute();
|
||||
@@ -252,9 +252,6 @@ class InstancesView extends InstancesViewBase {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private class MyFilteringCallback implements FilteringTaskCallback {
|
||||
private final ErrorsValueGroup myErrorsGroup = new ErrorsValueGroup();
|
||||
private final EvaluationContextImpl myEvaluationContext;
|
||||
@@ -284,8 +281,8 @@ class InstancesView extends InstancesViewBase {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Action matched(@NotNull Value ref) {
|
||||
final JavaValue val = new InstanceJavaValue(new InstanceValueDescriptor(myDebugProcess.getProject(), ref),
|
||||
public Action matched(@NotNull JavaReferenceInfo ref) {
|
||||
final JavaValue val = new InstanceJavaValue(ref.createDescriptor(myDebugProcess.getProject()),
|
||||
myEvaluationContext, myNodeManager);
|
||||
myMatchedCount++;
|
||||
myProceedCount++;
|
||||
@@ -298,7 +295,7 @@ class InstancesView extends InstancesViewBase {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Action notMatched(@NotNull Value ref) {
|
||||
public Action notMatched(@NotNull JavaReferenceInfo ref) {
|
||||
myProceedCount++;
|
||||
updateProgress();
|
||||
|
||||
@@ -307,8 +304,8 @@ class InstancesView extends InstancesViewBase {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Action error(@NotNull Value ref, @NotNull String description) {
|
||||
final JavaValue val = new InstanceJavaValue(new InstanceValueDescriptor(myDebugProcess.getProject(), ref),
|
||||
public Action error(@NotNull JavaReferenceInfo ref, @NotNull String description) {
|
||||
final JavaValue val = new InstanceJavaValue(ref.createDescriptor(myDebugProcess.getProject()),
|
||||
myEvaluationContext, myNodeManager);
|
||||
myErrorsGroup.addErrorValue(description, val);
|
||||
myProceedCount++;
|
||||
@@ -364,9 +361,9 @@ class InstancesView extends InstancesViewBase {
|
||||
}
|
||||
}
|
||||
private static class MyValuesList implements FilteringTask.ValuesList {
|
||||
private final List<? extends ObjectReference> myRefs;
|
||||
private final List<? extends JavaReferenceInfo> myRefs;
|
||||
|
||||
MyValuesList(List<? extends ObjectReference> refs) {
|
||||
MyValuesList(List<? extends JavaReferenceInfo> refs) {
|
||||
myRefs = refs;
|
||||
}
|
||||
|
||||
@@ -376,14 +373,14 @@ class InstancesView extends InstancesViewBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectReference get(int index) {
|
||||
public JavaReferenceInfo get(int index) {
|
||||
return myRefs.get(index);
|
||||
}
|
||||
}
|
||||
private class MyFilteringWorker extends SwingWorker<Void, Void> {
|
||||
private final FilteringTask myTask;
|
||||
|
||||
MyFilteringWorker(@NotNull List<ObjectReference> refs,
|
||||
MyFilteringWorker(@NotNull List<JavaReferenceInfo> refs,
|
||||
@NotNull XExpression expression,
|
||||
@NotNull EvaluationContextImpl evaluationContext) {
|
||||
myTask = new FilteringTask(myClassName, myDebugProcess, expression, new MyValuesList(refs),
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
// Copyright 2000-2018 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.debugger.memory.ui;
|
||||
|
||||
import com.intellij.debugger.memory.utils.InstanceValueDescriptor;
|
||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.xdebugger.memory.ui.ReferenceInfo;
|
||||
import com.sun.jdi.ObjectReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -12,6 +15,10 @@ public class JavaReferenceInfo implements ReferenceInfo {
|
||||
this.objectReference = objectReference;
|
||||
}
|
||||
|
||||
public ValueDescriptorImpl createDescriptor(@NotNull Project project) {
|
||||
return new InstanceValueDescriptor(project, objectReference);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ObjectReference getObjectReference() {
|
||||
return objectReference;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// 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.debugger.memory.ui;
|
||||
|
||||
import com.intellij.debugger.memory.utils.InstanceValueDescriptor;
|
||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.sun.jdi.ObjectReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SizedReferenceInfo extends JavaReferenceInfo {
|
||||
private final long mySize;
|
||||
|
||||
public SizedReferenceInfo(@NotNull ObjectReference objectReference, long size) {
|
||||
super(objectReference);
|
||||
mySize = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueDescriptorImpl createDescriptor(@NotNull Project project) {
|
||||
return new SizedValueDescriptor(project, getObjectReference());
|
||||
}
|
||||
|
||||
public long size() {
|
||||
return mySize;
|
||||
}
|
||||
|
||||
private class SizedValueDescriptor extends InstanceValueDescriptor {
|
||||
protected SizedValueDescriptor(@NotNull Project project, @NotNull ObjectReference value) {
|
||||
super(project, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String calcValueName() {
|
||||
return " [" + mySize + "] " + super.calcValueName();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user