Issue #2648 Enhance hprof output for grids and UI activity.

Former-commit-id: aae0dd9677 [formerly 31bbdb3d4d] [formerly 91270be4f7] [formerly aae0dd9677 [formerly 31bbdb3d4d] [formerly 91270be4f7] [formerly a401c4bed0 [formerly 91270be4f7 [formerly 80e4b1bdff46f8e1c77ba50b696e8bef5e53d51e]]]]
Former-commit-id: a401c4bed0
Former-commit-id: 49f2f26f3b [formerly eccaf37aee] [formerly bbe5ca014327b356aa992a01543461da5e29ab6e [formerly f4075f5fa5]]
Former-commit-id: 3cd7e963f7ba31f81b8582945e23b631917ba9b3 [formerly 911994f3ec]
Former-commit-id: f88b3b7455
This commit is contained in:
Ben Steffensmeier 2014-01-20 13:00:54 -06:00
parent 00a84ac3ec
commit 11ac88548a
7 changed files with 381 additions and 70 deletions

View file

@ -55,6 +55,15 @@ public class Id implements Comparable<Id> {
buffer.get(id);
}
public boolean isNull() {
for (byte b : id) {
if (b != 0x00) {
return false;
}
}
return true;
}
public int size() {
return id.length;
}

View file

@ -114,6 +114,10 @@ public class SmartInstance {
return type;
}
public boolean getBoolean(String fieldName) {
return getTypeNotNull(fieldName).getBoolean();
}
public int getInt(String fieldName) {
return getTypeNotNull(fieldName).getInt();
}
@ -183,7 +187,8 @@ public class SmartInstance {
public String getString(String fieldName) {
Id fieldId = getId(fieldName);
if (fieldId == null) {
return null;
throw new IllegalStateException(fieldName
+ " is not a a valid field");
}
InstanceDump field = hprof.getHeapDump().getInstance(fieldId);
if (field != null) {
@ -192,6 +197,8 @@ public class SmartInstance {
throw new IllegalStateException(fieldName + " is not a String.");
}
return smartField.toString();
} else if (fieldId.isNull()) {
return null;
} else {
Iterator<ClassDump> classDumps = hprof.getHeapDump()
.getClassDumps();

View file

@ -81,6 +81,7 @@ public class CaveExporter {
new InputHandlerExporter(hprof, outputDir).export();
new D2DProcedureDialogExporter(hprof, outputDir).export();
new GFEResourceExporter(hprof, outputDir).export();
new DisposingResourceExporter(hprof, outputDir).export();
new UIRunnablesExporter(hprof, outputDir).export();
}
}

View file

@ -53,7 +53,7 @@ import com.raytheon.hprof.SmartInstance;
*/
public class D2DGridResourceExporter extends RequestableResourceExporter {
private final boolean useDataMap = false;
private static final boolean useDataMap = false;
public D2DGridResourceExporter(HprofFile hprof, File outputDirectory) {
super(hprof, outputDirectory, null);
@ -93,45 +93,58 @@ public class D2DGridResourceExporter extends RequestableResourceExporter {
}
println("# Section 2 size and type of all GeneralGridData.");
Map<SmartInstance, Integer> sizes = new HashMap<SmartInstance, Integer>();
if (useDataMap) {
for (SmartInstance resource : resources) {
int floats = 0;
for (SmartInstance resource : resources) {
int floats = 0;
List<GeneralGridDataInstance> datas = new ArrayList<GeneralGridDataInstance>();
if (useDataMap) {
ConcurrentHashMap<SmartInstance, SmartInstance> dataMap = resource
.get("dataMap").toConcurrentHashMap();
if (!dataMap.isEmpty()) {
println(resource + "{");
for (Entry<SmartInstance, SmartInstance> dataEntry : dataMap
.entrySet()) {
List<SmartInstance> dataList = dataEntry.getValue()
.toArrayList();
for (SmartInstance gridData : dataList) {
floats += outputGeneralGridData(gridData);
}
for (Entry<SmartInstance, SmartInstance> dataEntry : dataMap
.entrySet()) {
List<SmartInstance> dataList = dataEntry.getValue()
.toArrayList();
for (SmartInstance gridData : dataList) {
datas.add(new GeneralGridDataInstance(gridData));
}
println("}");
}
sizes.put(resource, floats);
}
} else {
for (SmartInstance resource : resources) {
int floats = 0;
} else {
ArrayList<SmartInstance> requests = resource.get("requestJob")
.get("requests").toArrayList();
if (!requests.isEmpty()) {
println(resource + "{");
for (SmartInstance request : requests) {
SmartInstance data = request.get("gridData");
if (data != null) {
List<SmartInstance> dataList = data.toArrayList();
for (SmartInstance gridData : dataList) {
floats += outputGeneralGridData(gridData);
}
for (SmartInstance request : requests) {
SmartInstance data = request.get("gridData");
if (data != null) {
List<SmartInstance> dataList = data.toArrayList();
for (SmartInstance gridData : dataList) {
datas.add(new GeneralGridDataInstance(gridData));
}
}
println("}");
}
sizes.put(resource, floats);
}
if (datas.isEmpty()) {
continue;
}
println(resource + "{");
Map<GeneralGridDataInstance, Integer> redundantCounts = new HashMap<GeneralGridDataInstance, Integer>();
for (GeneralGridDataInstance gridDataInst : datas) {
int count = 0;
if (redundantCounts.containsKey(gridDataInst)) {
count = redundantCounts.get(gridDataInst);
}
count += 1;
redundantCounts.put(gridDataInst, count);
floats += gridDataInst.getFloatCount();
}
for (Entry<GeneralGridDataInstance, Integer> entry : redundantCounts
.entrySet()) {
sizes.put(resource, floats);
println(" " + entry.getValue()
+ " instances of GeneralGridData like {");
println(entry.getKey().toString());
println(" }");
}
println("}");
}
println("# Section 3 total size of each resource.");
List<Entry<SmartInstance, Integer>> sizesList = new ArrayList<Entry<SmartInstance, Integer>>(
@ -148,6 +161,23 @@ public class D2DGridResourceExporter extends RequestableResourceExporter {
int totalFloats = 0;
for (Entry<SmartInstance, Integer> entry : sizesList) {
SmartInstance resource = entry.getKey();
StringBuilder modHint = new StringBuilder();
try {
boolean dataModified = resource.getBoolean("dataModified");
modHint.append("(dataModified=").append(dataModified)
.append(")");
} catch (IllegalStateException e) {
/* heap dump is from before 14.2 */
}
try {
boolean reprojectedData = resource
.getBoolean("reprojectedData");
modHint.append("(reprojectedData=").append(reprojectedData)
.append(")");
} catch (IllegalStateException e) {
/* heap dump is from after 14.2 */
}
resource.getBoolean("reprojectedData");
int floats = entry.getValue();
int size = floats * 4 / 1024;
String suffix = "KB";
@ -155,7 +185,8 @@ public class D2DGridResourceExporter extends RequestableResourceExporter {
size /= 1024;
suffix = "MB";
}
println(resource + " uses is " + size + suffix);
println(resource.toString() + modHint.toString() + " uses is "
+ size + suffix);
totalFloats += floats;
}
println("# Section 4 total size of all resources.");
@ -163,44 +194,122 @@ public class D2DGridResourceExporter extends RequestableResourceExporter {
+ " resources is " + totalFloats * 4 / 1024 / 1024 + "MB");
}
protected int outputGeneralGridData(SmartInstance generalGridData)
throws IOException {
println(" " + generalGridData + "{");
SmartInstance gridGeometry = generalGridData.get("gridGeometry");
SmartInstance gridRange = gridGeometry.get("gridRange");
int[] index = gridRange.getIntArray("index");
int width = index[2] - index[0];
int height = index[3] - index[1];
println(" dimensions are " + width + "x" + height + "");
private static class GeneralGridDataInstance {
private final int width;
private final int height;
/* number of floats */
private final int scalarCapacity;
/* number of floats */
private final int dirCapacity;
/* number of floats */
private final int uCapacity;
/* number of floats */
private final int vCapacity;
public GeneralGridDataInstance(SmartInstance generalGridData) {
SmartInstance gridGeometry = generalGridData.get("gridGeometry");
SmartInstance gridRange = gridGeometry.get("gridRange");
int[] index = gridRange.getIntArray("index");
width = index[2] - index[0];
height = index[3] - index[1];
SmartInstance buffer = generalGridData.get("scalarData");
scalarCapacity = getCapacity(buffer);
buffer = generalGridData.get("direction");
dirCapacity = getCapacity(buffer);
buffer = generalGridData.get("uComponent");
uCapacity = getCapacity(buffer);
buffer = generalGridData.get("vComponent");
vCapacity = getCapacity(buffer);
int floats = 0;
SmartInstance buffer = generalGridData.get("scalarData");
if (buffer != null) {
int capacity = buffer.getInt("capacity");
println(" scalarData contains " + capacity + " floats.");
floats += capacity;
}
buffer = generalGridData.get("direction");
if (buffer != null) {
int capacity = buffer.getInt("capacity");
println(" direction contains " + capacity + " floats.");
floats += capacity;
private static int getCapacity(SmartInstance buffer) {
if (buffer == null) {
return 0;
}
try {
return buffer.getInt("capacity");
} catch (IllegalStateException e) {
return buffer.get("buffer").getInt("capacity");
}
}
buffer = generalGridData.get("uComponent");
if (buffer != null) {
int capacity = buffer.getInt("capacity");
println(" uComponent contains " + capacity + " floats.");
floats += capacity;
public int getFloatCount() {
return uCapacity + vCapacity + scalarCapacity + dirCapacity;
}
buffer = generalGridData.get("vComponent");
if (buffer != null) {
int capacity = buffer.getInt("capacity");
println(" vComponent contains " + capacity + " floats.");
floats += capacity;
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append(" dimensions are " + width + "x" + height + "\n");
if (scalarCapacity != 0) {
str.append(" scalarData contains " + scalarCapacity
+ " floats.\n");
}
if (dirCapacity != 0) {
str.append(" direction contains " + dirCapacity
+ " floats.\n");
}
if (uCapacity != 0) {
str.append(" uComponent contains " + uCapacity
+ " floats.\n");
}
if (vCapacity != 0) {
str.append(" vComponent contains " + vCapacity
+ " floats.\n");
}
str.append(" memory usage is " + getFloatCount() * 4 / 1024
+ "KB");
return str.toString();
}
println(" memory usage is " + floats * 4 / 1024 + "KB");
println(" }");
return floats;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + dirCapacity;
result = prime * result + height;
result = prime * result + scalarCapacity;
result = prime * result + uCapacity;
result = prime * result + vCapacity;
result = prime * result + width;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
GeneralGridDataInstance other = (GeneralGridDataInstance) obj;
if (dirCapacity != other.dirCapacity)
return false;
if (height != other.height)
return false;
if (scalarCapacity != other.scalarCapacity)
return false;
if (uCapacity != other.uCapacity)
return false;
if (vCapacity != other.vCapacity)
return false;
if (width != other.width)
return false;
return true;
}
}
}

View file

@ -71,13 +71,26 @@ public class DisplayedResourcesExporter extends DisplayPaneContainerExporter {
}
@Override
protected void outputPaneManager(
SmartInstance paneManager) throws IOException {
protected void outputPaneManager(SmartInstance paneManager)
throws IOException {
List<SmartInstance> displayPanes = paneManager.get("displayPanes")
.toArrayList();
for (SmartInstance dispalyPane : displayPanes) {
SmartInstance descriptor = dispalyPane.get("renderableDisplay")
.get("descriptor");
SmartInstance renderableDisplay = dispalyPane
.get("renderableDisplay");
try {
String scale = renderableDisplay.getString("scaleName");
println(" scaleName = " + scale);
} catch (IllegalStateException e) {
/* Not D2D or after 14.2 */
}
try {
String scale = renderableDisplay.getString("scale");
println(" scale = " + scale);
} catch (IllegalStateException e) {
/* Not D2D or before 14.2 */
}
SmartInstance descriptor = renderableDisplay.get("descriptor");
SmartInstance resourceList = descriptor.get("resourceList");
SmartInstance[] array = resourceList.getObjectArray("array");
println(" " + descriptor + "{");
@ -99,6 +112,7 @@ public class DisplayedResourcesExporter extends DisplayPaneContainerExporter {
println(" }");
}
}
public List<SmartInstance> getResources() {
return resources;
}

View file

@ -0,0 +1,83 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.hprof;
import java.io.File;
import java.io.IOException;
import java.util.List;
import com.raytheon.hprof.HprofFile;
import com.raytheon.hprof.SmartInstance;
/**
*
* Export information about the resources waiting to dispose.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Jan 20, 2014 2648 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class DisposingResourceExporter extends AbstractExporter {
public DisposingResourceExporter(HprofFile hprof, File outputDirectory) {
super(hprof, outputDirectory);
}
@Override
protected String getFileName() {
return "disposingResources.txt";
}
@Override
protected String getComment() {
StringBuilder comment = new StringBuilder();
comment.append("# This file contains resources that are waiting for the ResourceCatalog to\n");
comment.append("# dispose them. These resources have already been removed from displays and are\n");
comment.append("# waiting for asyncronous access to the UI thread.");
return comment.toString();
}
@Override
protected String getInfo() {
return "Generating output for disposing Resources...";
}
@Override
protected void exportInternal() throws IOException {
List<SmartInstance> runnables = getInstances("com.raytheon.uf.viz.core.rsc.ResourceCatalog$1");
if (runnables.isEmpty()) {
return;
}
for (SmartInstance runnable : runnables) {
SmartInstance resource = runnable.get("val$resource");
println(resource.toString());
}
}
}

View file

@ -0,0 +1,88 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.hprof;
import java.io.File;
import java.io.IOException;
import java.util.List;
import com.raytheon.hprof.HprofFile;
import com.raytheon.hprof.SmartInstance;
/**
*
* Export information about the runnables waiting to execute on the UI Thread.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Jan 20, 2014 2648 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class UIRunnablesExporter extends AbstractExporter {
public UIRunnablesExporter(HprofFile hprof, File outputDirectory) {
super(hprof, outputDirectory);
}
@Override
protected String getFileName() {
return "uiRunnables.txt";
}
@Override
protected String getComment() {
StringBuilder comment = new StringBuilder();
comment.append("# This file contains runnables waiting for access to the SWT UI Thread. These are\n");
comment.append("# often scheduled through VizApp.runAsync.");
return comment.toString();
}
@Override
protected String getInfo() {
return "Generating output for UI Runnables...";
}
@Override
protected void exportInternal() throws IOException {
List<SmartInstance> displays = getInstances("org.eclipse.swt.widgets.Display");
if (displays.isEmpty()) {
return;
}
println(displays.size() + " dispaly(s)");
for (SmartInstance display : displays) {
SmartInstance[] messages = display.get("synchronizer")
.getObjectArray("messages");
println(messages.length + " message(s)");
for (SmartInstance message : messages) {
println(message.get("runnable").toString());
}
}
}
}