/*
* 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.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
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 static final NumberFormat NUMBER_FORMATTER = NumberFormat.getInstance();
private List<NativeAllocationInfo> mHeapAllocations;
private List<NativeLibraryAllocationInfo> mHeapAllocationsByLibrary;
private List<NativeAllocationInfo> mNonZygoteHeapAllocations;
private List<NativeLibraryAllocationInfo> mNonZygoteHeapAllocationsByLibrary;
private long mTotalSize;
public NativeHeapSnapshot(List<NativeAllocationInfo> heapAllocations) {
mHeapAllocations = heapAllocations;
// precompute the total size as this is always needed.
mTotalSize = getTotalMemory(heapAllocations);
}
protected long getTotalMemory(Collection<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;
}
public String getFormattedMemorySize() {
return String.format("%s bytes", formatMemorySize(getTotalSize()));
}
protected String formatMemorySize(long memSize) {
return NUMBER_FORMATTER.format(memSize);
}
public List<NativeAllocationInfo> getNonZygoteAllocations() {
if (mNonZygoteHeapAllocations != null) {
return mNonZygoteHeapAllocations;
}
// filter out all zygote allocations
mNonZygoteHeapAllocations = new ArrayList<NativeAllocationInfo>();
for (NativeAllocationInfo info : mHeapAllocations) {
if (info.isZygoteChild()) {
mNonZygoteHeapAllocations.add(info);
}
}
return mNonZygoteHeapAllocations;
}
public List<NativeLibraryAllocationInfo> getNonZygoteAllocationsByLibrary() {
if (mNonZygoteHeapAllocationsByLibrary != null) {
return mNonZygoteHeapAllocationsByLibrary;
}
List<NativeLibraryAllocationInfo> heapAllocations =
NativeLibraryAllocationInfo.constructFrom(getNonZygoteAllocations());
// cache for future uses only if it is fully resolved.
if (isFullyResolved(heapAllocations)) {
mNonZygoteHeapAllocationsByLibrary = heapAllocations;
}
return heapAllocations;
}
}