Issue #2648 Enhance hprof output for grids and UI activity.
Former-commit-id:91270be4f7
[formerly 80e4b1bdff46f8e1c77ba50b696e8bef5e53d51e] Former-commit-id:a401c4bed0
This commit is contained in:
parent
83c27d7025
commit
f4075f5fa5
7 changed files with 381 additions and 70 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue