You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by jt...@apache.org on 2021/03/16 20:35:41 UTC
[netbeans] branch master updated: Avoid displaying classloader
fields when there is at most single classloader in the dump
This is an automated email from the ASF dual-hosted git repository.
jtulach pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new e2e6fb4 Avoid displaying classloader fields when there is at most single classloader in the dump
new a299d76 Merge pull request #2809 from JaroslavTulach/jtulach/UnnecessaryClassLoaders
e2e6fb4 is described below
commit e2e6fb4be4534e0d79d89f90b64b66033000609f
Author: Jaroslav Tulach <ja...@apidesign.org>
AuthorDate: Fri Mar 12 20:50:16 2021 +0100
Avoid displaying classloader fields when there is at most single classloader in the dump
---
.../lib/profiler/heap/HeapSegmentTest.java | 40 ++++++++++--
.../org/netbeans/lib/profiler/heap/HeapUtils.java | 3 +-
profiler/profiler.heapwalker/nbproject/project.xml | 15 +++++
.../profiler/heapwalk/ClassesController.java | 2 +-
.../profiler/heapwalk/FieldsBrowserController.java | 25 ++++---
.../profiler/heapwalk/HeapFragmentWalker.java | 20 ++++++
.../profiler/heapwalk/InstancesController.java | 3 +-
.../profiler/heapwalk/InstancesListController.java | 5 ++
.../profiler/heapwalk/OverviewController.java | 14 +---
.../heapwalk/model/AbstractHeapWalkerNode.java | 6 +-
.../profiler/heapwalk/model/BrowserUtils.java | 4 +-
.../profiler/heapwalk/model/HeapWalkerNode.java | 2 +
.../profiler/heapwalk/model/ObjectArrayNode.java | 2 +-
.../profiler/heapwalk/model/ObjectFieldNode.java | 2 +-
.../profiler/heapwalk/model/ObjectNode.java | 15 ++++-
.../heapwalk/model/PrimitiveArrayNode.java | 2 +-
.../heapwalk/ui/FieldsBrowserControllerUI.java | 2 +-
.../heapwalk/model/HeapWalkerNodeTest.java | 76 ++++++++++++++++++++++
18 files changed, 198 insertions(+), 40 deletions(-)
diff --git a/profiler/lib.profiler/test/unit/src/org/netbeans/lib/profiler/heap/HeapSegmentTest.java b/profiler/lib.profiler/test/unit/src/org/netbeans/lib/profiler/heap/HeapSegmentTest.java
index 6141829..e2c6f20 100644
--- a/profiler/lib.profiler/test/unit/src/org/netbeans/lib/profiler/heap/HeapSegmentTest.java
+++ b/profiler/lib.profiler/test/unit/src/org/netbeans/lib/profiler/heap/HeapSegmentTest.java
@@ -21,7 +21,10 @@ package org.netbeans.lib.profiler.heap;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
@@ -29,6 +32,7 @@ import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.netbeans.lib.profiler.heap.HeapUtils.HprofGenerator;
@@ -37,16 +41,15 @@ public class HeapSegmentTest {
public void singleObject() throws IOException {
singleObject(false);
}
-
+
@Test
public void singleObjectMultipleSegments() throws IOException {
singleObject(true);
}
-
+
private static void singleObject(boolean flush) throws IOException {
File mydump = File.createTempFile("mydump", ".hprof");
- generateSingleObject(new FileOutputStream(mydump), flush);
- Heap heap = HeapFactory.createHeap(mydump);
+ Heap heap = generateSampleDump(mydump, flush);
List<JavaClass> allClasses = heap.getAllClasses();
assertEquals(5, allClasses.size());
assertEquals("java.lang.String", allClasses.get(0).getName());
@@ -77,13 +80,38 @@ public class HeapSegmentTest {
assertFalse("It is not daemon", (Boolean) daemon);
}
+ public static Heap generateSampleDump(File mydump) throws IOException {
+ return generateSampleDump(mydump, true);
+ }
+
+ public static Heap generateComplexDump(File mydump) throws IOException, URISyntaxException {
+ InputStream is = HeapUtils.class.getResourceAsStream("heap_dump.bin");
+ FileOutputStream out = new FileOutputStream(mydump);
+ byte[] arr = new byte[4096];
+ for (;;) {
+ int len = is.read(arr);
+ if (len == -1) {
+ break;
+ }
+ out.write(arr, 0, len);
+ }
+ is.close();
+ out.close();
+ return HeapFactory.createHeap(mydump);
+ }
+
+ static Heap generateSampleDump(File mydump, boolean flush) throws IOException {
+ generateSingleObject(new FileOutputStream(mydump), flush);
+ return HeapFactory.createHeap(mydump);
+ }
+
private static void generateSingleObject(OutputStream os, boolean flush) throws IOException {
try (HprofGenerator gen = new HprofGenerator(os)) {
gen.writeHeapSegment(new SampleDumpMemory(), flush);
gen.writeHeapSegment(new SampleDumpMemory2(), flush);
}
}
-
+
private static class SampleDumpMemory implements HprofGenerator.Generator<HprofGenerator.HeapSegment> {
@Override
public void generate(HprofGenerator.HeapSegment seg) throws IOException {
@@ -118,5 +146,5 @@ public class HeapSegmentTest {
seg.dumpPrimitive(threadId);
}
}
-
+
}
diff --git a/profiler/lib.profiler/test/unit/src/org/netbeans/lib/profiler/heap/HeapUtils.java b/profiler/lib.profiler/test/unit/src/org/netbeans/lib/profiler/heap/HeapUtils.java
index 6f7a57c..115c99c 100644
--- a/profiler/lib.profiler/test/unit/src/org/netbeans/lib/profiler/heap/HeapUtils.java
+++ b/profiler/lib.profiler/test/unit/src/org/netbeans/lib/profiler/heap/HeapUtils.java
@@ -328,7 +328,6 @@ final class HeapUtils {
.dumpClass();
}
generator.generate(seg);
- seg.close();
}
@Override
@@ -435,5 +434,5 @@ final class HeapUtils {
return stringId;
}
}
-
+
}
diff --git a/profiler/profiler.heapwalker/nbproject/project.xml b/profiler/profiler.heapwalker/nbproject/project.xml
index b332570..c29a5f7 100644
--- a/profiler/profiler.heapwalker/nbproject/project.xml
+++ b/profiler/profiler.heapwalker/nbproject/project.xml
@@ -161,6 +161,21 @@
</run-dependency>
</dependency>
</module-dependencies>
+ <test-dependencies>
+ <test-type>
+ <name>unit</name>
+ <test-dependency>
+ <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
+ <recursive/>
+ <compile-dependency/>
+ </test-dependency>
+ <test-dependency>
+ <code-name-base>org.netbeans.lib.profiler</code-name-base>
+ <compile-dependency/>
+ <test/>
+ </test-dependency>
+ </test-type>
+ </test-dependencies>
<friend-packages>
<friend>com.sun.tools.visualvm.heapdump</friend>
<friend>com.sun.tools.visualvm.heapviewer</friend>
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/ClassesController.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/ClassesController.java
index 5d9ebcd..a4eb87e 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/ClassesController.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/ClassesController.java
@@ -78,7 +78,7 @@ public class ClassesController extends AbstractTopLevelController implements Fie
this.heapFragmentWalker = heapFragmentWalker;
classesListController = new ClassesListController(this);
- staticFieldsBrowserController = new FieldsBrowserController(this, FieldsBrowserController.ROOT_CLASS);
+ staticFieldsBrowserController = new FieldsBrowserController(this, FieldsBrowserController.ROOT_CLASS, true);
}
//~ Methods ------------------------------------------------------------------------------------------------------------------
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/FieldsBrowserController.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/FieldsBrowserController.java
index 8529f91..272d490 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/FieldsBrowserController.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/FieldsBrowserController.java
@@ -42,6 +42,8 @@ import javax.swing.tree.TreePath;
"FieldsBrowserController_NoneString=<none>"
})
public class FieldsBrowserController extends AbstractController {
+
+ private final boolean showClassLoaders;
//~ Inner Interfaces ---------------------------------------------------------------------------------------------------------
public static interface Handler {
@@ -136,11 +138,11 @@ public class FieldsBrowserController extends AbstractController {
protected String computeValue() {
return Bundle.FieldsBrowserController_NoneString();
}
-
+
protected String computeSize() {
return ""; // NOI18N
}
-
+
protected String computeRetainedSize() {
return ""; // NOI18N
}
@@ -165,8 +167,13 @@ public class FieldsBrowserController extends AbstractController {
//~ Constructors -------------------------------------------------------------------------------------------------------------
public FieldsBrowserController(Handler instancesControllerHandler, int rootMode) {
+ this(instancesControllerHandler, rootMode, true);
+ }
+
+ public FieldsBrowserController(Handler instancesControllerHandler, int rootMode, boolean showClassLoaders) {
this.instancesControllerHandler = instancesControllerHandler;
this.rootMode = rootMode;
+ this.showClassLoaders = showClassLoaders;
}
//~ Methods ------------------------------------------------------------------------------------------------------------------
@@ -244,15 +251,15 @@ public class FieldsBrowserController extends AbstractController {
protected AbstractButton createControllerPresenter() {
return ((FieldsBrowserControllerUI) getPanel()).getPresenter();
}
-
+
public List getExpandedPaths() {
return ((FieldsBrowserControllerUI)getPanel()).getExpandedPaths();
}
-
+
public TreePath getSelectedRow() {
return ((FieldsBrowserControllerUI)getPanel()).getSelectedRow();
}
-
+
public void restoreState(List expanded, TreePath selected) {
((FieldsBrowserControllerUI)getPanel()).restoreState(expanded, selected);
}
@@ -263,10 +270,12 @@ public class FieldsBrowserController extends AbstractController {
}
private HeapWalkerNode getFields(final Instance instance) {
+ int fieldsMode = showClassLoaders ? HeapWalkerNode.MODE_FIELDS : HeapWalkerNode.MODE_FIELDS_NO_CLASSLOADER;
+
return HeapWalkerNodeFactory.createRootInstanceNode(instance, "this", // NOI18N
new Runnable() { public void run() { ((FieldsBrowserControllerUI) getPanel()).refreshView(); } },
new Runnable() { public void run() { getPanel().repaint(); } },
- HeapWalkerNode.MODE_FIELDS, instancesControllerHandler.getHeapFragmentWalker().getHeapFragment());
+ fieldsMode, instancesControllerHandler.getHeapFragmentWalker().getHeapFragment());
}
private HeapWalkerNode getFields(final JavaClass javaClass) {
@@ -278,13 +287,13 @@ public class FieldsBrowserController extends AbstractController {
private HeapWalkerNode getFilteredFields(HeapWalkerNode fields, String filterValue) {
// ArrayList filteredFields = new ArrayList();
- //
+ //
// Iterator fieldsIterator = fields.iterator();
// while (fieldsIterator.hasNext()) {
// FieldValue field = (FieldValue)fieldsIterator.next();
// if (matchesFilter(field)) filteredFields.add(field);
// }
- //
+ //
// return filteredFields;
return fields;
}
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/HeapFragmentWalker.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/HeapFragmentWalker.java
index 55cf36b..4033479 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/HeapFragmentWalker.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/HeapFragmentWalker.java
@@ -23,6 +23,7 @@ import org.netbeans.lib.profiler.heap.*;
import org.netbeans.modules.profiler.heapwalk.ui.HeapFragmentWalkerUI;
import java.io.File;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
@@ -318,6 +319,25 @@ public class HeapFragmentWalker {
return null;
}
+ private Integer classLoaderCount;
+ public final int countClassLoaders() {
+ if (this.classLoaderCount != null) {
+ return this.classLoaderCount;
+ }
+ int nclassloaders = 0;
+ JavaClass cl = heapFragment.getJavaClassByName("java.lang.ClassLoader"); // NOI18N
+ if (cl != null) {
+ nclassloaders = cl.getInstancesCount();
+
+ Collection<JavaClass> jcs = cl.getSubClasses();
+
+ for (JavaClass jc : jcs) {
+ nclassloaders += jc.getInstancesCount();
+ }
+ }
+ return this.classLoaderCount = nclassloaders;
+ }
+
public static interface StateListener {
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/InstancesController.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/InstancesController.java
index 4a71cd7..1f8f886 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/InstancesController.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/InstancesController.java
@@ -98,7 +98,8 @@ public class InstancesController extends AbstractTopLevelController implements F
public void refresh() { setJavaClass(selectedClass); }
};
instancesListController = new InstancesListController(this);
- fieldsBrowserController = new FieldsBrowserController(this, FieldsBrowserController.ROOT_INSTANCE);
+ boolean showClassLoaders = heapFragmentWalker.countClassLoaders() > 1;
+ fieldsBrowserController = new FieldsBrowserController(this, FieldsBrowserController.ROOT_INSTANCE, showClassLoaders);
referencesBrowserController = new ReferencesBrowserController(this);
classPresenter.setHeapFragmentWalker(heapFragmentWalker);
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/InstancesListController.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/InstancesListController.java
index 83bab97..0ee6811 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/InstancesListController.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/InstancesListController.java
@@ -487,6 +487,11 @@ public class InstancesListController extends AbstractController {
return 0;
}
+ @Override
+ public boolean isModeFields() {
+ return false;
+ }
+
public int getNChildren() {
return 0;
}
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/OverviewController.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/OverviewController.java
index 25c60dd..cf5d924 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/OverviewController.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/OverviewController.java
@@ -137,21 +137,11 @@ public class OverviewController extends AbstractController {
Heap heap = heapFragmentWalker.getHeapFragment();
HeapSummary hsummary = heap.getSummary();
long finalizers = computeFinalizers(heap);
- int nclassloaders = 0;
- JavaClass cl = heap.getJavaClassByName("java.lang.ClassLoader"); // NOI18N
NumberFormat numberFormat = (NumberFormat)NumberFormat.getInstance().clone();
numberFormat.setMaximumFractionDigits(1);
oome = getOOMEThread(heap);
- if (cl != null) {
- nclassloaders = cl.getInstancesCount();
-
- Collection<JavaClass> jcs = cl.getSubClasses();
-
- for (JavaClass jc : jcs) {
- nclassloaders += jc.getInstancesCount();
- }
- }
+ int nclassloaders = heapFragmentWalker.countClassLoaders();
String filename = LINE_PREFIX
+ Bundle.OverviewController_FileItemString(
@@ -202,7 +192,7 @@ public class OverviewController extends AbstractController {
+ Bundle.OverviewController_SummaryString() + "</b><br><hr>" + dateTaken + "<br>" + filename + "<br>" + filesize + "<br><br>" + liveBytes // NOI18N
+ "<br>" + liveClasses + "<br>" + liveInstances + "<br>" + classloaders + "<br>" + gcroots + "<br>" + finalizersInfo + oomeString; // NOI18N
}
-
+
public String computeEnvironment() {
String sysinfoRes = Icons.getResource(HeapWalkerIcons.SYSTEM_INFO);
String header = "<b><img border='0' align='bottom' src='nbresloc:/" + sysinfoRes + "'> " // NOI18N
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/AbstractHeapWalkerNode.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/AbstractHeapWalkerNode.java
index 6da91ac..6557f09 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/AbstractHeapWalkerNode.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/AbstractHeapWalkerNode.java
@@ -41,7 +41,7 @@ public abstract class AbstractHeapWalkerNode extends HeapWalkerNode {
private String size;
private String retainedSize;
private HeapWalkerNode[] children;
- private int mode = HeapWalkerNode.MODE_FIELDS;
+ private final int mode;
private Map<Object, Integer> indexes;
@@ -107,6 +107,10 @@ public abstract class AbstractHeapWalkerNode extends HeapWalkerNode {
return getNChildren() == 0;
}
+ public final boolean isModeFields() {
+ return mode != MODE_REFERENCES;
+ }
+
public int getMode() {
return mode;
}
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/BrowserUtils.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/BrowserUtils.java
index e04c042..6bdf519 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/BrowserUtils.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/BrowserUtils.java
@@ -307,13 +307,13 @@ public class BrowserUtils {
}
private static String pathFromRoot(TreePath path) {
- int m = ((HeapWalkerNode)path.getLastPathComponent()).getMode();
+ final HeapWalkerNode last = (HeapWalkerNode)path.getLastPathComponent();
Object[] nodes = path.getPath();
StringBuilder b = new StringBuilder();
int s = nodes.length;
for (int i = 0; i < s; i++) {
HeapWalkerNode n = (HeapWalkerNode)nodes[i];
- if (m == HeapWalkerNode.MODE_FIELDS) fieldFromRoot(n, b, i, s);
+ if (last.isModeFields()) fieldFromRoot(n, b, i, s);
else referenceFromRoot(n, b, i, s);
b.append("\n"); // NOI18N
}
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/HeapWalkerNode.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/HeapWalkerNode.java
index d8624a7..aacf326 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/HeapWalkerNode.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/HeapWalkerNode.java
@@ -38,6 +38,7 @@ public abstract class HeapWalkerNode extends CCTNode {
public static final int MODE_FIELDS = 1;
public static final int MODE_REFERENCES = 2;
+ public static final int MODE_FIELDS_NO_CLASSLOADER = 3;
//~ Methods ------------------------------------------------------------------------------------------------------------------
@@ -83,6 +84,7 @@ public abstract class HeapWalkerNode extends CCTNode {
* There are two different algorithms for generating childs in both Browsers.
*/
public abstract int getMode();
+ public abstract boolean isModeFields();
public static TreePath fromNode(TreeNode node) {
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/ObjectArrayNode.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/ObjectArrayNode.java
index 874b226..171ee45 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/ObjectArrayNode.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/ObjectArrayNode.java
@@ -127,7 +127,7 @@ public class ObjectArrayNode extends ArrayNode {
public HeapWalkerNode[] computeChildren() {
HeapWalkerNode[] children = null;
- if (getMode() == HeapWalkerNode.MODE_FIELDS) {
+ if (isModeFields()) {
int fieldsSize = getInstance().getLength();
if (fieldsSize == 0) {
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/ObjectFieldNode.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/ObjectFieldNode.java
index f36425b..665f163 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/ObjectFieldNode.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/ObjectFieldNode.java
@@ -40,7 +40,7 @@ public class ObjectFieldNode extends ObjectNode implements HeapWalkerFieldNode {
}
public ObjectFieldNode(ObjectFieldValue fieldValue, HeapWalkerNode parent, int mode) {
- super((mode == HeapWalkerNode.MODE_FIELDS) ? fieldValue.getInstance() : fieldValue.getDefiningInstance(),
+ super((mode != HeapWalkerNode.MODE_REFERENCES) ? fieldValue.getInstance() : fieldValue.getDefiningInstance(),
fieldValue.getField().getName(), parent, mode);
this.fieldValue = fieldValue;
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/ObjectNode.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/ObjectNode.java
index 3be984a..a2c17a6 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/ObjectNode.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/ObjectNode.java
@@ -24,6 +24,7 @@ import org.openide.util.NbBundle;
import java.util.ArrayList;
import javax.swing.Icon;
import javax.swing.ImageIcon;
+import org.netbeans.lib.profiler.heap.Field;
import org.netbeans.lib.profiler.heap.FieldValue;
import org.netbeans.lib.profiler.heap.GCRoot;
import org.netbeans.lib.profiler.heap.Instance;
@@ -141,13 +142,21 @@ public class ObjectNode extends InstanceNode {
public HeapWalkerNode[] computeChildren() {
HeapWalkerNode[] children = null;
- if (getMode() == HeapWalkerNode.MODE_FIELDS) {
+ if (isModeFields()) {
if (hasInstance()) {
ArrayList fieldValues = new ArrayList();
fieldValues.addAll(getInstance().getFieldValues());
- fieldValues.addAll(getInstance().getStaticFieldValues());
+ final boolean skipClassLoaders = getMode() == HeapWalkerNode.MODE_FIELDS_NO_CLASSLOADER;
+ for (Object v : getInstance().getStaticFieldValues()) {
+ FieldValue fv = (FieldValue) v;
+ final Field field = fv.getField();
+ if (skipClassLoaders && field.isStatic() && "<classLoader>".equals(field.getName())) { // NOI18N
+ continue;
+ }
+ fieldValues.add(v);
+ }
- if (fieldValues.size() == 0) {
+ if (fieldValues.isEmpty()) {
// Instance has no fields
children = new HeapWalkerNode[1];
children[0] = HeapWalkerNodeFactory.createNoFieldsNode(ObjectNode.this);
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/PrimitiveArrayNode.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/PrimitiveArrayNode.java
index bdc653a..58b1afc 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/PrimitiveArrayNode.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/PrimitiveArrayNode.java
@@ -128,7 +128,7 @@ public class PrimitiveArrayNode extends ArrayNode {
public HeapWalkerNode[] computeChildren() {
HeapWalkerNode[] children = null;
- if (getMode() == HeapWalkerNode.MODE_FIELDS) {
+ if (isModeFields()) {
int fieldsSize = getInstance().getLength();
if (fieldsSize == 0) {
diff --git a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/ui/FieldsBrowserControllerUI.java b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/ui/FieldsBrowserControllerUI.java
index 64247ad..3c90101 100644
--- a/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/ui/FieldsBrowserControllerUI.java
+++ b/profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/ui/FieldsBrowserControllerUI.java
@@ -153,7 +153,7 @@ public class FieldsBrowserControllerUI extends JTitledPanel {
}
public void mouseClicked(MouseEvent e) {
- if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
+ if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
int row = fieldsListTable.rowAtPoint(e.getPoint());
if (e.getX() >= fieldsListTable.getTree().getRowBounds(row).x -
fieldsListTable.getTreeCellOffsetX() && row != -1) {
diff --git a/profiler/profiler.heapwalker/test/unit/src/org/netbeans/modules/profiler/heapwalk/model/HeapWalkerNodeTest.java b/profiler/profiler.heapwalker/test/unit/src/org/netbeans/modules/profiler/heapwalk/model/HeapWalkerNodeTest.java
new file mode 100644
index 0000000..d967787
--- /dev/null
+++ b/profiler/profiler.heapwalker/test/unit/src/org/netbeans/modules/profiler/heapwalk/model/HeapWalkerNodeTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.profiler.heapwalk.model;
+
+import java.io.File;
+import org.netbeans.junit.NbTestCase;
+import org.netbeans.lib.profiler.heap.Heap;
+import org.netbeans.lib.profiler.heap.HeapSegmentTest;
+import org.netbeans.modules.profiler.heapwalk.HeapFragmentWalker;
+
+public class HeapWalkerNodeTest extends NbTestCase {
+
+ public HeapWalkerNodeTest(String n) {
+ super(n);
+ }
+
+ private static void assertChildMode(ObjectNode on) {
+ ObjectNode ch = new ObjectNode(null, "any", on);
+ assertEquals("Same mode on child", on.getMode(), ch.getMode());
+ }
+
+ public void testModeFields1() {
+ ObjectNode on = new ObjectNode(null, "any", null, HeapWalkerNode.MODE_FIELDS);
+ assertTrue("Showing fields", on.isModeFields());
+ assertChildMode(on);
+ }
+
+
+ public void testModeFields2() {
+ ObjectNode on = new ObjectNode(null, "any", null, HeapWalkerNode.MODE_FIELDS_NO_CLASSLOADER);
+ assertTrue("Showing fields", on.isModeFields());
+ assertChildMode(on);
+ }
+
+ public void testModeFields3() {
+ ObjectNode on = new ObjectNode(null, "any", null, HeapWalkerNode.MODE_REFERENCES);
+ assertFalse("Not showing fields", on.isModeFields());
+ assertChildMode(on);
+ }
+
+ public void testSimpleHeapDumpAnalysis() throws Exception {
+ clearWorkDir();
+ File mydump = new File(getWorkDir(), "sample.hprof");
+ mydump.getParentFile().mkdirs();
+ Heap heap = HeapSegmentTest.generateSampleDump(mydump);
+
+ HeapFragmentWalker walker = new HeapFragmentWalker(heap, null);
+ assertEquals("No classloaders", 0, walker.countClassLoaders());
+ }
+
+ public void testComplexHeapDumpAnalysis() throws Exception {
+ clearWorkDir();
+ File mydump = new File(getWorkDir(), "complex.hprof");
+ mydump.getParentFile().mkdirs();
+ Heap heap = HeapSegmentTest.generateComplexDump(mydump);
+
+ HeapFragmentWalker walker = new HeapFragmentWalker(heap, null);
+ assertEquals("Heap dump uses some classloaders", 2, walker.countClassLoaders());
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists