diff options
author | Siva Velusamy <vsiva@google.com> | 2011-09-22 11:33:08 -0700 |
---|---|---|
committer | Siva Velusamy <vsiva@google.com> | 2011-09-22 11:47:56 -0700 |
commit | 34692855c8b9313b10e71b7ba13990167f1fcda1 (patch) | |
tree | 9b33f26b10fe4a17bca8db69fe1d4cedbd9f8bb3 /ddms/libs | |
parent | db0d88169bc8dd8e2f38090feab572336a72bc92 (diff) | |
download | sdk-34692855c8b9313b10e71b7ba13990167f1fcda1.zip sdk-34692855c8b9313b10e71b7ba13990167f1fcda1.tar.gz sdk-34692855c8b9313b10e71b7ba13990167f1fcda1.tar.bz2 |
Support grouping of allocations by library.
Currently, all allocations are displayed as a list sorted by
the size of the allocation.
This patch set enables the toolbar checkbox to group the list of
allocations by library. When this is checked, the display refreshes
to show a tree with the root nodes being libraries, and their
children being the list of allocations made from that library.
Change-Id: Ibb61242db8c6e58d300f767f0b2b11b6b7a9530d
Diffstat (limited to 'ddms/libs')
-rw-r--r-- | ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapLabelProvider.java | 24 | ||||
-rw-r--r-- | ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java | 75 | ||||
-rw-r--r-- | ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapProviderByAllocations.java (renamed from ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapContentProvider.java) | 21 | ||||
-rw-r--r-- | ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapProviderByLibrary.java | 69 | ||||
-rw-r--r-- | ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapSnapshot.java | 84 | ||||
-rw-r--r-- | ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeLibraryAllocationInfo.java | 134 |
6 files changed, 367 insertions, 40 deletions
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapLabelProvider.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapLabelProvider.java index c558cf0..df7598f 100644 --- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapLabelProvider.java +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapLabelProvider.java @@ -32,11 +32,18 @@ public class NativeHeapLabelProvider extends LabelProvider implements ITableLabe } public String getColumnText(Object element, int index) { - if (!(element instanceof NativeAllocationInfo)) { - return null; + if (element instanceof NativeAllocationInfo) { + return getColumnTextForNativeAllocation((NativeAllocationInfo) element, index); } - NativeAllocationInfo info = (NativeAllocationInfo) element; + if (element instanceof NativeLibraryAllocationInfo) { + return getColumnTextForNativeLibrary((NativeLibraryAllocationInfo) element, index); + } + + return null; + } + + private String getColumnTextForNativeAllocation(NativeAllocationInfo info, int index) { NativeStackCallInfo stackInfo = info.getRelevantStackCallInfo(); switch (index) { @@ -55,6 +62,17 @@ public class NativeHeapLabelProvider extends LabelProvider implements ITableLabe } } + private String getColumnTextForNativeLibrary(NativeLibraryAllocationInfo info, int index) { + switch (index) { + case 0: + return Long.toString(info.getTotalSize()); + case 3: + return info.getLibraryName(); + default: + return null; + } + } + private String stackResolutionStatus(NativeAllocationInfo info) { if (info.isStackCallResolved()) { return "?"; // resolved and unknown diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java index d2e415e..9ddb15f 100644 --- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java @@ -27,6 +27,7 @@ import com.android.ddmuilib.ImageLoader; import com.android.ddmuilib.TableHelper; import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.viewers.ILazyTreeContentProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; @@ -83,11 +84,12 @@ public class NativeHeapPanel extends BaseHeapPanel { private static final NumberFormat NUMBER_FORMATTER = NumberFormat.getInstance(); + private static final String PREFS_GROUP_BY_LIBRARY = "nativeheap.grouby.library"; private static final String PREFS_SYMBOL_SEARCH_PATH = "nativeheap.search.path"; private static final String PREFS_SASH_HEIGHT_PERCENT = "nativeheap.sash.percent"; private IPreferenceStore mPrefStore; - private List<List<NativeAllocationInfo>> mNativeHeapAllocations; + private List<NativeHeapSnapshot> mNativeHeapSnapshots; private Button mSnapshotHeapButton; private Text mSymbolSearchPathText; @@ -96,6 +98,8 @@ public class NativeHeapPanel extends BaseHeapPanel { private TreeViewer mDetailsTreeViewer; private TreeViewer mStackTraceTreeViewer; + private ILazyTreeContentProvider mContentProviderByAllocations; + private ILazyTreeContentProvider mContentProviderByLibrary; private ToolBar mDetailsToolBar; private ToolItem mGroupByButton; @@ -107,8 +111,9 @@ public class NativeHeapPanel extends BaseHeapPanel { mPrefStore = prefStore; mPrefStore.setDefault(PREFS_SASH_HEIGHT_PERCENT, 75); mPrefStore.setDefault(PREFS_SYMBOL_SEARCH_PATH, ""); + mPrefStore.setDefault(PREFS_GROUP_BY_LIBRARY, false); - mNativeHeapAllocations = new ArrayList<List<NativeAllocationInfo>>(); + mNativeHeapSnapshots = new ArrayList<NativeHeapSnapshot>(); } /** {@inheritDoc} */ @@ -130,7 +135,7 @@ public class NativeHeapPanel extends BaseHeapPanel { // the list on future updates allocations = shallowCloneList(allocations); - mNativeHeapAllocations.add(allocations); + mNativeHeapSnapshots.add(new NativeHeapSnapshot(allocations)); updateDisplay(); // Attempt to resolve symbols in a separate thread. @@ -163,11 +168,13 @@ public class NativeHeapPanel extends BaseHeapPanel { mSnapshotHeapButton.setEnabled(c != null); - mNativeHeapAllocations = new ArrayList<List<NativeAllocationInfo>>(); + mNativeHeapSnapshots = new ArrayList<NativeHeapSnapshot>(); if (c != null) { List<NativeAllocationInfo> allocations = c.getClientData().getNativeAllocationList(); + allocations = shallowCloneList(allocations); + if (allocations.size() > 0) { - mNativeHeapAllocations.add(allocations); + mNativeHeapSnapshots.add(new NativeHeapSnapshot(allocations)); } } @@ -179,10 +186,10 @@ public class NativeHeapPanel extends BaseHeapPanel { public void run() { updateSnapshotIndexCombo(); - List<NativeAllocationInfo> lastHeapSnapshot = null; - if (mNativeHeapAllocations.size() > 0) { + NativeHeapSnapshot lastHeapSnapshot = null; + if (mNativeHeapSnapshots.size() > 0) { lastHeapSnapshot = - mNativeHeapAllocations.get(mNativeHeapAllocations.size() - 1); + mNativeHeapSnapshots.get(mNativeHeapSnapshots.size() - 1); } displaySnapshot(lastHeapSnapshot); @@ -195,40 +202,41 @@ public class NativeHeapPanel extends BaseHeapPanel { Display.getDefault().syncExec(new Runnable() { public void run() { int idx = mSnapshotIndexCombo.getSelectionIndex(); - displaySnapshot(mNativeHeapAllocations.get(idx)); + displaySnapshot(mNativeHeapSnapshots.get(idx)); } }); } - private void displaySnapshot(List<NativeAllocationInfo> heapSnapshot) { - mDetailsTreeViewer.setInput(heapSnapshot); + private void displaySnapshot(NativeHeapSnapshot snapshot) { + mDetailsTreeViewer.setInput(snapshot); - if (heapSnapshot != null) { - mMemoryAllocatedText.setText(formatMemorySize(getTotalMemory(heapSnapshot))); + if (snapshot != null) { + mMemoryAllocatedText.setText(formatMemorySize(snapshot.getTotalSize())); mMemoryAllocatedText.pack(); } else { mMemoryAllocatedText.setText(""); } } - private String formatMemorySize(long totalMemory) { - return NUMBER_FORMATTER.format(totalMemory) + " bytes"; - } - - private long getTotalMemory(List<NativeAllocationInfo> heapSnapshot) { - long total = 0; + private void updateDisplayGrouping() { + boolean groupByLibrary = mGroupByButton.getSelection(); + mPrefStore.setValue(PREFS_GROUP_BY_LIBRARY, groupByLibrary); - for (NativeAllocationInfo info : heapSnapshot) { - total += info.getAllocationCount() * info.getSize(); + if (groupByLibrary) { + mDetailsTreeViewer.setContentProvider(mContentProviderByLibrary); + } else { + mDetailsTreeViewer.setContentProvider(mContentProviderByAllocations); } + } - return total; + private String formatMemorySize(long totalMemory) { + return NUMBER_FORMATTER.format(totalMemory) + " bytes"; } private void updateSnapshotIndexCombo() { List<String> items = new ArrayList<String>(); - int numSnapshots = mNativeHeapAllocations.size(); + int numSnapshots = mNativeHeapSnapshots.size(); for (int i = 0; i < numSnapshots; i++) { // offset indices by 1 so that users see index starting at 1 rather than 0 items.add("Snapshot " + (i + 1)); @@ -336,6 +344,7 @@ public class NativeHeapPanel extends BaseHeapPanel { } }); mSymbolSearchPathText.setText(mPrefStore.getString(PREFS_SYMBOL_SEARCH_PATH)); + mSymbolSearchPathText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); } private void updateSearchPath(String path) { @@ -434,6 +443,13 @@ public class NativeHeapPanel extends BaseHeapPanel { mGroupByButton.setImage(ImageLoader.getDdmUiLibLoader().loadImage(GROUPBY_IMAGE, toolbar.getDisplay())); mGroupByButton.setToolTipText(TOOLTIP_GROUPBY); + mGroupByButton.setSelection(mPrefStore.getBoolean(PREFS_GROUP_BY_LIBRARY)); + mGroupByButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent arg0) { + updateDisplayGrouping(); + } + }); mDiffsOnlyButton = new ToolItem(toolbar, SWT.CHECK); mDiffsOnlyButton.setImage(ImageLoader.getDdmUiLibLoader().loadImage(DIFFS_ONLY_IMAGE, @@ -452,7 +468,6 @@ public class NativeHeapPanel extends BaseHeapPanel { mExportHeapDataButton.setToolTipText(TOOLTIP_EXPORT_DATA); // disable all toolbar items until they implement the necessary features - mGroupByButton.setEnabled(false); mDiffsOnlyButton.setEnabled(false); mShowZygoteAllocationsButton.setEnabled(false); mExportHeapDataButton.setEnabled(false); @@ -497,7 +512,15 @@ public class NativeHeapPanel extends BaseHeapPanel { mDetailsTreeViewer = new TreeViewer(tree); mDetailsTreeViewer.setUseHashlookup(true); - mDetailsTreeViewer.setContentProvider(new NativeHeapContentProvider(mDetailsTreeViewer)); + + mContentProviderByAllocations = new NativeHeapProviderByAllocations(mDetailsTreeViewer); + mContentProviderByLibrary = new NativeHeapProviderByLibrary(mDetailsTreeViewer); + if (mPrefStore.getBoolean(PREFS_GROUP_BY_LIBRARY)) { + mDetailsTreeViewer.setContentProvider(mContentProviderByLibrary); + } else { + mDetailsTreeViewer.setContentProvider(mContentProviderByAllocations); + } + mDetailsTreeViewer.setLabelProvider(new NativeHeapLabelProvider()); mDetailsTreeViewer.setInput(null); @@ -588,7 +611,7 @@ public class NativeHeapPanel extends BaseHeapPanel { } public void run() { - for (NativeAllocationInfo callSite: mCallSites) { + for (NativeAllocationInfo callSite : mCallSites) { if (callSite.isStackCallResolved()) { continue; } diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapContentProvider.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapProviderByAllocations.java index 6e651b3..a85bea5 100644 --- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapContentProvider.java +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapProviderByAllocations.java @@ -20,17 +20,16 @@ import org.eclipse.jface.viewers.ILazyTreeContentProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; -import java.util.List; - /** * Content Provider for the native heap tree viewer in {@link NativeHeapPanel}. - * It expects a list of {@link NativeAllocationInfo} objects as input. + * It expects a {@link NativeHeapSnapshot} as input, and provides the list of allocations + * in the heap dump as content to the UI. */ -public final class NativeHeapContentProvider implements ILazyTreeContentProvider { +public final class NativeHeapProviderByAllocations implements ILazyTreeContentProvider { private TreeViewer mViewer; - private List<?> mCurrentAllocations; + private NativeHeapSnapshot mNativeHeapDump; - public NativeHeapContentProvider(TreeViewer viewer) { + public NativeHeapProviderByAllocations(TreeViewer viewer) { mViewer = viewer; } @@ -38,7 +37,7 @@ public final class NativeHeapContentProvider implements ILazyTreeContentProvider } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - mCurrentAllocations = (List <?>) newInput; + mNativeHeapDump = (NativeHeapSnapshot) newInput; } public Object getParent(Object arg0) { @@ -48,8 +47,8 @@ public final class NativeHeapContentProvider implements ILazyTreeContentProvider public void updateChildCount(Object element, int currentChildCount) { int childCount = 0; - if (element == mCurrentAllocations) { // root element - childCount = mCurrentAllocations.size(); + if (element == mNativeHeapDump) { // root element + childCount = mNativeHeapDump.getAllocations().size(); } mViewer.setChildCount(element, childCount); @@ -58,8 +57,8 @@ public final class NativeHeapContentProvider implements ILazyTreeContentProvider public void updateElement(Object parent, int index) { Object item = null; - if (parent == mCurrentAllocations) { // root element - item = mCurrentAllocations.get(index); + if (parent == mNativeHeapDump) { // root element + item = mNativeHeapDump.getAllocations().get(index); } mViewer.replace(parent, index, item); diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapProviderByLibrary.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapProviderByLibrary.java new file mode 100644 index 0000000..858b104 --- /dev/null +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapProviderByLibrary.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed 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 com.android.ddmuilib.heap; + +import org.eclipse.jface.viewers.ILazyTreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; + +/** + * Content Provider for the native heap tree viewer in {@link NativeHeapPanel}. + * It expects input of type {@link NativeHeapSnapshot}, and provides heap allocations + * grouped by library to the UI. + */ +public class NativeHeapProviderByLibrary implements ILazyTreeContentProvider { + private TreeViewer mViewer; + + public NativeHeapProviderByLibrary(TreeViewer viewer) { + mViewer = viewer; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + public Object getParent(Object element) { + return null; + } + + public void updateChildCount(Object element, int currentChildCount) { + int childCount = 0; + + if (element instanceof NativeHeapSnapshot) { + childCount = ((NativeHeapSnapshot) element).getAllocationsByLibrary().size(); + } + + mViewer.setChildCount(element, childCount); + } + + public void updateElement(Object parent, int index) { + Object item = null; + int childCount = 0; + + if (parent instanceof NativeHeapSnapshot) { // root element + item = ((NativeHeapSnapshot) parent).getAllocationsByLibrary().get(index); + childCount = ((NativeLibraryAllocationInfo) item).getAllocations().size(); + } else if (parent instanceof NativeLibraryAllocationInfo) { + item = ((NativeLibraryAllocationInfo) parent).getAllocations().get(index); + } + + mViewer.replace(parent, index, item); + mViewer.setChildCount(item, childCount); + } +} diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapSnapshot.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapSnapshot.java new file mode 100644 index 0000000..d8dd342 --- /dev/null +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapSnapshot.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed 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 com.android.ddmuilib.heap; + +import com.android.ddmlib.NativeAllocationInfo; + +import java.util.List; + +/** + * A Native Heap Snapshot models a single heap dump. + * + * It primarily consists of a list of {@link NativeAllocationInfo} objects. From this list, + * other objects of interest to the UI are computed and cached for future use. + */ +public class NativeHeapSnapshot { + private List<NativeAllocationInfo> mHeapAllocations; + private List<NativeLibraryAllocationInfo> mHeapAllocationsByLibrary; + private long mTotalSize; + + public NativeHeapSnapshot(List<NativeAllocationInfo> heapAllocations) { + mHeapAllocations = heapAllocations; + + // precompute the total size as this is always needed. + mTotalSize = getTotalMemory(heapAllocations); + } + + private long getTotalMemory(List<NativeAllocationInfo> heapSnapshot) { + long total = 0; + + for (NativeAllocationInfo info : heapSnapshot) { + total += info.getAllocationCount() * info.getSize(); + } + + return total; + } + + public List<NativeAllocationInfo> getAllocations() { + return mHeapAllocations; + } + + public List<NativeLibraryAllocationInfo> getAllocationsByLibrary() { + if (mHeapAllocationsByLibrary != null) { + return mHeapAllocationsByLibrary; + } + + List<NativeLibraryAllocationInfo> heapAllocations = + NativeLibraryAllocationInfo.constructFrom(mHeapAllocations); + + // cache for future uses only if it is fully resolved. + if (isFullyResolved(heapAllocations)) { + mHeapAllocationsByLibrary = heapAllocations; + } + + return heapAllocations; + } + + private boolean isFullyResolved(List<NativeLibraryAllocationInfo> heapAllocations) { + for (NativeLibraryAllocationInfo info : heapAllocations) { + if (info.getLibraryName().equals(NativeLibraryAllocationInfo.UNRESOLVED_LIBRARY_NAME)) { + return false; + } + } + + return true; + } + + public long getTotalSize() { + return mTotalSize; + } +} diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeLibraryAllocationInfo.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeLibraryAllocationInfo.java new file mode 100644 index 0000000..7bc2649 --- /dev/null +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeLibraryAllocationInfo.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed 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 com.android.ddmuilib.heap; + +import com.android.ddmlib.NativeAllocationInfo; +import com.android.ddmlib.NativeStackCallInfo; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A heap dump representation where each call site is associated with its source library. + */ +public final class NativeLibraryAllocationInfo { + /** Library name to use when grouping before symbol resolution is complete. */ + public static final String UNRESOLVED_LIBRARY_NAME = "Resolving.."; + + /** Any call site that cannot be resolved to a specific library goes under this name. */ + private static final String UNKNOWN_LIBRARY_NAME = "unknown"; + + private final String mLibraryName; + private final List<NativeAllocationInfo> mHeapAllocations; + private int mTotalSize; + + private NativeLibraryAllocationInfo(String libraryName) { + mLibraryName = libraryName; + mHeapAllocations = new ArrayList<NativeAllocationInfo>(); + } + + private void addAllocation(NativeAllocationInfo info) { + mHeapAllocations.add(info); + } + + private void updateTotalSize() { + mTotalSize = 0; + for (NativeAllocationInfo i : mHeapAllocations) { + mTotalSize += i.getAllocationCount() * i.getSize(); + } + } + + public String getLibraryName() { + return mLibraryName; + } + + public long getTotalSize() { + return mTotalSize; + } + + public List<NativeAllocationInfo> getAllocations() { + return mHeapAllocations; + } + + /** + * Factory method to create a list of {@link NativeLibraryAllocationInfo} objects, + * given the list of {@link NativeAllocationInfo} objects. + * + * If the {@link NativeAllocationInfo} objects do not have their symbols resolved, + * then they are grouped under the library {@link #UNRESOLVED_LIBRARY_NAME}. If they do + * have their symbols resolved, but map to an unknown library, then they are grouped under + * the library {@link #UNKNOWN_LIBRARY_NAME}. + */ + public static List<NativeLibraryAllocationInfo> constructFrom( + List<NativeAllocationInfo> allocations) { + if (allocations == null) { + return null; + } + + Map<String, NativeLibraryAllocationInfo> allocationsByLibrary = + new HashMap<String, NativeLibraryAllocationInfo>(); + + // go through each native allocation and assign it to the appropriate library + for (NativeAllocationInfo info : allocations) { + String libName = UNRESOLVED_LIBRARY_NAME; + + if (info.isStackCallResolved()) { + NativeStackCallInfo relevantStackCall = info.getRelevantStackCallInfo(); + if (relevantStackCall != null) { + libName = relevantStackCall.getLibraryName(); + } else { + libName = UNKNOWN_LIBRARY_NAME; + } + } + + addtoLibrary(allocationsByLibrary, libName, info); + } + + List<NativeLibraryAllocationInfo> libraryAllocations = + new ArrayList<NativeLibraryAllocationInfo>(allocationsByLibrary.values()); + + // now update some summary statistics for each library + for (NativeLibraryAllocationInfo l : libraryAllocations) { + l.updateTotalSize(); + } + + // finally, sort by total size + Collections.sort(libraryAllocations, new Comparator<NativeLibraryAllocationInfo>() { + public int compare(NativeLibraryAllocationInfo o1, + NativeLibraryAllocationInfo o2) { + return (int) (o2.getTotalSize() - o1.getTotalSize()); + } + }); + + return libraryAllocations; + } + + private static void addtoLibrary(Map<String, NativeLibraryAllocationInfo> libraryAllocations, + String libName, NativeAllocationInfo info) { + NativeLibraryAllocationInfo libAllocationInfo = libraryAllocations.get(libName); + if (libAllocationInfo == null) { + libAllocationInfo = new NativeLibraryAllocationInfo(libName); + libraryAllocations.put(libName, libAllocationInfo); + } + + libAllocationInfo.addAllocation(info); + } +} |