917 lines
32 KiB
Plaintext
917 lines
32 KiB
Plaintext
page.title=Memory Monitor
|
||
parent.title=Android Monitor
|
||
parent.link=android-monitor.html
|
||
page.tags=monitor
|
||
@jd:body
|
||
|
||
<div id="qv-wrapper">
|
||
<div id="qv">
|
||
<h2>In this document</h2>
|
||
<ol>
|
||
<li><a href="#workflow">Memory Monitor Workflow</a>
|
||
<ol>
|
||
<li><a href="#treeroot">Garbage collection roots and dominator trees</a></li>
|
||
<li><a href="#analysis">Memory leak and use analysis</a></li>
|
||
<li><a href="#vm">Memory management for different virtual machines</a></li>
|
||
</ol>
|
||
</li>
|
||
<li><a href="#displaying">Displaying a Running App in the Memory Monitor</a></li>
|
||
<li><a href="#forcing">Forcing a Garbage Collection Event</a></li>
|
||
<li><a href="#dumping">Dumping and Analyzing the Java Heap</a>
|
||
<ol>
|
||
<li><a href="#hprof-snapshot">Taking and displaying a snapshot of the Java heap</a></li>
|
||
<li><a href="#hprof-diving">Diving into heap dump data in the HPROF Viewer</a></li>
|
||
<li><a href="#hprof-analyzing">Analyzing heap dump data in the HPROF Analyzer</a></li>
|
||
<li><a href="#hprof-sorting">Sorting heap dump data</a></li>
|
||
<li><a href="#hprof-source">Displaying Java source</a></li>
|
||
<li><a href="#hprof-viewing">Viewing a saved HPROF file</a></li>
|
||
<li><a href="#hprof-renaming">Renaming an HPROF file</a></li>
|
||
<li><a href="#hprof-locating">Locating a heap dump file on disk</a></li>
|
||
<li><a href="#hprof-deleting">Deleting a heap dump file</a></li>
|
||
<li><a href="#hprof-converting">Converting a heap dump file to standard HPROF format</a></li>
|
||
</ol>
|
||
</li>
|
||
<li><a href="#tracking">Tracking and Analyzing Memory Allocation</a>
|
||
<ol>
|
||
<li><a href="#alloc-snapshot">Taking and displaying a snapshot of allocation data</a></li>
|
||
<li><a href="#alloc-sorting">Sorting allocation data</a></li>
|
||
<li><a href="#alloc-source">Displaying Java source</a></li>
|
||
<li><a href="#alloc-viewing">Viewing a saved allocation tracking file</a></li>
|
||
<li><a href="#alloc-renaming">Renaming an allocation tracking file</a></li>
|
||
<li><a href="#alloc-locating">Locating an allocation tracking file</a></li>
|
||
<li><a href="#alloc-deleting">Deleting an allocation tracking file</a></li>
|
||
</ol>
|
||
</li>
|
||
</ol>
|
||
|
||
<h2>See also</h2>
|
||
<ol>
|
||
<li><a href="{@docRoot}training/articles/memory.html">Managing Your App's Memory</a></li>
|
||
<li><a href="{@docRoot}guide/practices/verifying-apps-art.html#GC_Migration">Addressing Garbage Collection Issues</a></li>
|
||
<li><a href="{@docRoot}tools/debugging/debugging-memory.html">Investigating Your RAM Usage</a></li>
|
||
|
||
<li>
|
||
<a href="{@docRoot}tools/help/android-monitor.html">Android Monitor</a>
|
||
</li>
|
||
<li><a href="{@docRoot}tools/help/am-logcat.html">logcat Monitor</a>
|
||
</li>
|
||
|
||
<li><a href="{@docRoot}tools/help/am-cpu.html">CPU Monitor</a>
|
||
</li>
|
||
|
||
<li><a href="{@docRoot}tools/help/am-gpu.html">GPU Monitor</a>
|
||
</li>
|
||
|
||
<li>
|
||
<a href="{@docRoot}tools/help/am-network.html">Network Monitor</a>
|
||
</li>
|
||
</ol>
|
||
|
||
|
||
<h2>
|
||
Dependencies and Prerequisites
|
||
</h2>
|
||
|
||
<ul>
|
||
<li>
|
||
Make sure your development computer detects your hardware device, which often happens
|
||
automatically when you connect it to a USB port.
|
||
</li>
|
||
<li>
|
||
<a href="{@docRoot}tools/device.html#device-developer-options">Enable</a> <strong><a href=
|
||
"{@docRoot}tools/device.html#device-developer-options">USB debugging</a></strong> in
|
||
<strong>Developer Options</strong> on the device or emulator.
|
||
</li>
|
||
|
||
<li>In your app, set the <code>debuggable</code> property to <code>true</code> in the manifest or
|
||
<code>build.gradle</code> file (it’s initially set by default).
|
||
</li>
|
||
|
||
<li>Enable ADB integration through <strong>Tools</strong> > <strong>Android</strong> >
|
||
<strong>Enable ADB Integration</strong>.
|
||
</li>
|
||
|
||
<li>
|
||
<a href="{@docRoot}tools/help/monitor.html">Android Device Monitor</a> can’t be running.
|
||
</li>
|
||
</ul>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<p>
|
||
Android Studio provides a Memory Monitor so you can more easily monitor app performance and
|
||
memory usage to find deallocated objects, locate memory leaks, and track the amount of memory the
|
||
connected device is using. The Memory Monitor reports how your app allocates memory and helps you
|
||
to visualize the memory your app uses. It lets you:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>Show a graph of available and allocated memory over time.
|
||
</li>
|
||
<li>Show garbage collection (GC) events
|
||
over time.
|
||
</li>
|
||
<li>Initiate garbage collection events.
|
||
</li>
|
||
|
||
<li>Quickly test whether app slowness might be related to excessive garbage collection events.
|
||
</li>
|
||
|
||
<li>Quickly test whether app crashes may be related to running out of memory.
|
||
</li>
|
||
</ul>
|
||
|
||
<h2 id="workflow">
|
||
Memory Monitor Workflow
|
||
</h2>
|
||
|
||
<p>
|
||
To profile and optimize memory use, the typical workflow is to run your app and do the following:
|
||
</p>
|
||
|
||
<ol>
|
||
<li>Profile the app using the Memory Monitor to find out whether undesirable garbage collection
|
||
event patterns might be causing performance problems.
|
||
</li>
|
||
|
||
<li>If you see many garbage collection events in a short amount of time, dump the Java heap to
|
||
identify candidate object types that get or stay allocated unexpectedly or unnecessarily.
|
||
</li>
|
||
|
||
<li>Start allocation tracking to determine where any problems are happening in your code.
|
||
</li>
|
||
</ol>
|
||
|
||
<p>
|
||
The Java heap data shows in real-time what types of objects your application has allocated, how
|
||
many, and their sizes on the heap. Viewing the heap helps you to:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>Get a sense of how your app allocates and frees memory.
|
||
</li>
|
||
|
||
<li>Identify memory leaks.
|
||
</li>
|
||
</ul>
|
||
|
||
<p>
|
||
Allocation tracking records app memory allocations and lists all allocations for the
|
||
profiling cycle, including the call stack, size, and allocating code. It helps you to:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>Identify where many similar object types, from roughly the same call stack, are allocated and
|
||
deallocated over a very short period of time.
|
||
</li>
|
||
|
||
<li>Find the places in your code that may contribute to inefficient memory use.
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 id="treeroot">
|
||
Garbage collection roots and dominator trees
|
||
</h3>
|
||
|
||
<p>
|
||
When you dump the Java heap, the Memory Monitor creates an Android-specific Heap/CPU Profiling
|
||
(HPROF) file that you can view in the HPROF Viewer. The HPROF Viewer indicates a garbage
|
||
collection root with the <img src="{@docRoot}images/tools/am-igcroot.png"
|
||
style="vertical-align:sub;margin:0;height:17px" alt="GC Root icon" /> icon (and a depth of zero)
|
||
and a
|
||
dominator with the <img src="{@docRoot}images/tools/am-idom.png"
|
||
style="vertical-align:sub;margin:0;height:17px" alt="Dominator icon" /> icon.
|
||
</p>
|
||
|
||
<p>
|
||
There are several kinds of garbage collection roots in Java:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>references on the stack</li>
|
||
<li>Java Native Interface (JNI) native objects and memory</li>
|
||
<li>static variables and functions</li>
|
||
<li>threads and objects that can be referenced </li>
|
||
<li>classes loaded by the bootstrap loader</li>
|
||
<li>finalizers and unfinalized objects</li>
|
||
<li>busy monitor objects</li>
|
||
</ul>
|
||
|
||
<p>
|
||
The HPROF file provides the list of roots to the HPROF Viewer.
|
||
</p>
|
||
|
||
<p>
|
||
A dominator tree traces paths to objects created by the app. An object dominates another object
|
||
if the only way to reach the other object is, directly or indirectly, through the dominator
|
||
object. When you examine objects and paths created by an app in an effort to optimize memory use,
|
||
try to remove objects that are no longer needed. You can release a dominator object to
|
||
release all subordinate objects. For example, in the following figure, if you were to
|
||
remove object B, that would also release the memory used by the objects it dominates, which are
|
||
objects C, D, E, and F. In fact, if objects C, D, E, and F were marked for removal, but object B
|
||
was still referring to them, that could be the reason that they weren’t released.
|
||
</p>
|
||
|
||
<img src="{@docRoot}images/tools/am-domtree.png" height="200" />
|
||
|
||
<h3 id="analysis">
|
||
Memory leak and use analysis
|
||
</h3>
|
||
|
||
<p>
|
||
An app performs better if it uses memory efficiently and releases the memory when it’s no longer
|
||
needed.
|
||
Memory leaks that are large or that grow over time are the most important to correct.
|
||
</p>
|
||
|
||
<p>
|
||
One way to optimize memory usage is to analyze large arrays. For example, can you reduce the size
|
||
of individual elements in the array to save memory? Does a dominator object point to
|
||
an element in the array, preventing it from being garbage-collected? If the dominator object
|
||
directly points to an element in the array, the dominator is either the contiguous memory
|
||
representing the underlying data of the array, some part of the array, or the array itself.
|
||
</p>
|
||
|
||
<p>
|
||
Another area that deserves attention is objects that the app no longer needs but continues to
|
||
reference. You can gather heap dumps over different periods of time and compare them to determine
|
||
if you have a growing memory leak, such as an object type that your code creates multiple times
|
||
but doesn’t destroy. These objects could be part of a growing array or an object tree, for
|
||
example. To track down this problem, compare the heap dumps and see if you have a particular
|
||
object type that continues to have more and more instances over time.
|
||
</p>
|
||
|
||
<p>
|
||
Continually growing object trees that contain root or dominator objects can prevent subordinate
|
||
objects from being garbage-collected. This issue is a common cause of memory leaks, out-of-memory
|
||
errors,
|
||
and crashes. Your app could have a small number of objects that are preventing a large number of
|
||
subordinate objects from being destroyed, so it runs out of memory quickly. To find these issues,
|
||
get a heap dump and examine the amount of memory held by root and dominator objects. If the
|
||
memory is substantial, you’ve likely found a good place to start optimizing your memory use.
|
||
</p>
|
||
|
||
<p>
|
||
As you start narrowing down memory issues, you should also use the Allocation Tracker to get a
|
||
better understanding of where your memory-hogging objects are allocated. The Allocation Tracker
|
||
can be valuable not only for looking at specific uses of memory, but also for analyzing critical
|
||
code paths, such as loading and scrolling. For example, tracking allocations when flinging a list
|
||
in your app
|
||
allows you to see all of the allocations that need to be done for that behavior, what thread they
|
||
are on, and where they came from. This information is extremely valuable for tightening up these
|
||
paths to reduce the work they need and improve the overall smoothness of the UI.
|
||
</p>
|
||
|
||
<p>
|
||
It’s useful to examine your algorithms for allocations that are unnecessary or that create the
|
||
same object many times instead of reusing them. For example, do you create temporary objects and
|
||
variables within recursive loops? If so, try creating an object or variable before
|
||
the loop for use within the loop. Otherwise, your app might needlessly allocate many objects and
|
||
variables, depending on the number of recursions.
|
||
</p>
|
||
|
||
<p>
|
||
It’s important to perform allocation tests on portions of your code that create the most and
|
||
largest objects, as those areas offer the most optimization opportunities. In addition to unit
|
||
tests, you should test your app with production-realistic data loads, especially those algorithms
|
||
that are data-driven. Also, make sure to account for the app caching and startup phase, which can
|
||
sometimes be slow; allocation analysis is best done after that phase to produce accurate results.
|
||
</p>
|
||
|
||
<p>
|
||
After you optimize code, be sure to test that it worked. You need to test under different load
|
||
conditions and also without running the Memory Monitor tools. Compare results before and after
|
||
optimization to make sure that performance has actually improved.
|
||
</p>
|
||
|
||
<h3 id="vm">
|
||
Memory management for different virtual machines
|
||
</h3>
|
||
|
||
<p>
|
||
Android Monitor uses the Virtual Machine (VM) that the device or emulator uses:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>Android 4.3 (API level 18) and lower uses the Dalvik VM.
|
||
</li>
|
||
|
||
<li>In Android 4.4 (API level 19), the Android RunTime (ART) VM is an option, while the Dalvik VM
|
||
is the default.
|
||
</li>
|
||
|
||
<li>Android 5.0 (API level 21) and higher uses the ART VM.
|
||
</li>
|
||
</ul>
|
||
|
||
<p>
|
||
The VM handles garbage collection. The Dalvik VM uses a mark-and-sweep scheme for garbage
|
||
collection. The ART VM uses a generational scheme, combined with mark-and-sweep when memory needs
|
||
a more thorough garbage collection, such as when memory becomes excessively fragmented. The
|
||
logcat Monitor displays some messages that indicate the type of garbage collection that occurred
|
||
and why.
|
||
</p>
|
||
|
||
<p>
|
||
Memory Monitor results can vary between the different VMs. As a result, if you’re supporting both
|
||
VMs, you might want to test with both. In addition, the VMs available for different API levels
|
||
can have different behavior. For example, the Dalvik VM in Android 2.3 (API level 10) and lower
|
||
uses externally allocated memory while higher versions allocate in the Dalvik heap only.
|
||
</p>
|
||
|
||
<p>
|
||
You can’t reconfigure the Dalvik and ART VMs to tune performance. Instead, you should examine
|
||
your app code to determine how to improve its operation, for example, reducing the size of very
|
||
large arrays.
|
||
</p>
|
||
|
||
<p>
|
||
There are programmatic ways to manipulate when the VM performs garbage collection, although it’s
|
||
not a best practice. These techniques can be specific to the VM. For more information, see
|
||
<a href=
|
||
"{@docRoot}guide/practices/verifying-apps-art.html#GC_Migration">Addressing
|
||
Garbage Collection (GC) Issues</a> and <a href=
|
||
"{@docRoot}tools/debugging/debugging-memory.html">Investigating Your RAM
|
||
Usage</a>.
|
||
</p>
|
||
|
||
<p>
|
||
The ART VM adds a number of performance, development, and debugging improvements over the Dalvik
|
||
VM. For more information, see <a href=
|
||
"https://source.android.com/devices/tech/dalvik/index.html">ART and Dalvik</a>.
|
||
</p>
|
||
|
||
<h2 id="displaying">
|
||
Displaying a Running App in the Memory Monitor
|
||
</h2>
|
||
|
||
<p>
|
||
Follow these steps:
|
||
</p>
|
||
|
||
<ol>
|
||
<li>Optionally connect a hardware device.
|
||
</li>
|
||
|
||
<li>
|
||
<a href=
|
||
"{@docRoot}tools/help/android-monitor.html#displaying">Display Android Monitor</a>.
|
||
</li>
|
||
|
||
<li>Click the <strong>Memory</strong> tab.
|
||
</li>
|
||
|
||
<li>Open an app project and <a href=
|
||
"{@docRoot}tools/building/building-studio.html#RunningApp">run it</a> on a
|
||
hardware device or emulator.
|
||
</li>
|
||
|
||
<li>Enable the Memory Monitor by clicking Pause <img src="{@docRoot}images/tools/am-ipause.png"
|
||
style="vertical-align:sub;margin:0;height:17px" alt="Pause icon" /> to deselect it.
|
||
</li>
|
||
|
||
|
||
<p>
|
||
In the graph, the y-axis displays the free and allocated RAM in megabytes. The x-axis shows the
|
||
time elapsed; it starts with seconds, and then minutes and seconds, and so on. The amount of free
|
||
memory, measured in megabytes,
|
||
is shown in a light color, and allocated memory is a darker color. When there’s a sharp drop in
|
||
allocated memory, that indicates a garbage collection event. </p>
|
||
|
||
|
||
|
||
<p>
|
||
To force a garbage collection event, click Initiate GC <img src="{@docRoot}images/tools/am-igc.png"
|
||
style="vertical-align:sub;margin:0;height:17px" alt="Initiate GC icon" />.
|
||
</p>
|
||
|
||
<p>In the following figure, the VM initiated the first garbage collection event, while the
|
||
developer forced the second.
|
||
</p>
|
||
<img src="{@docRoot}images/tools/am-gc.png" />
|
||
|
||
<li>Interact with your app and watch how it affects memory usage in the Memory Monitor. You can
|
||
identify garbage collection patterns for your app and determine whether they are healthy and what
|
||
you expect.
|
||
</li>
|
||
|
||
|
||
<p>
|
||
The graph can show you potential issues:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>Excessive garbage collection events slow down the app.
|
||
</li>
|
||
|
||
<li>The app runs out of memory, which causes it to crash.
|
||
</li>
|
||
|
||
<li>Potential memory leaks.
|
||
</li>
|
||
</ul>
|
||
|
||
<p>
|
||
For example, you might see the following signs of problems:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>Your app is static, but you see memory being allocated in the monitor.
|
||
</li>
|
||
|
||
<li>You see spikes of memory allocations in the monitor, but you don’t think there’s any app
|
||
logic to cause this behavior.
|
||
</li>
|
||
</ul>
|
||
<li>To stop the Memory Monitor, click Pause <img src="{@docRoot}images/tools/am-ipause.png"
|
||
style="vertical-align:sub;margin:0;height:17px" alt="Pause icon" /> again to select it.
|
||
</li>
|
||
|
||
</ol>
|
||
|
||
<h2 id="forcing">
|
||
Forcing a Garbage Collection Event
|
||
</h2>
|
||
|
||
<p>
|
||
Normally, VMs perform garbage collection only when absolutely needed, since it’s expensive.
|
||
However, it can be useful to force garbage collection in certain circumstances. For example, when
|
||
locating memory leaks, if you want to determine whether a large object was successfully released
|
||
already, you can initiate garbage collection much more aggressively than usual.
|
||
</p>
|
||
|
||
<p>
|
||
To force a garbage collection event:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>While the <a href="#displaying">Memory Monitor is running</a>, click Initiate GC
|
||
<img src="{@docRoot}images/tools/am-igc.png" style="vertical-align:sub;margin:0;height:17px"
|
||
alt="Initiate GC icon" />.
|
||
</li>
|
||
</ul>
|
||
|
||
<h2 id="dumping">
|
||
Dumping and Analyzing the Java Heap
|
||
</h2>
|
||
|
||
<p>
|
||
When you're monitoring memory usage in Android Studio you can, at the same time, dump the Java
|
||
heap to a heap snapshot in an Android-specific HPROF binary format file. The HPROF Viewer
|
||
displays classes, instances of each class, and a reference tree to help you track memory usage
|
||
and find memory leaks. HPROF is a heap dump format originally supported by J2SE.
|
||
</p>
|
||
<p>The Java heap display does the following:</p>
|
||
|
||
<ul>
|
||
<li>Shows snapshots of a number of objects allocated by type.
|
||
</li>
|
||
|
||
<li>Samples data every time a garbage collection event occurs naturally or is triggered by you.
|
||
</li>
|
||
|
||
<li>Helps identify which object types might be involved in memory leaks.
|
||
</li>
|
||
</ul>
|
||
|
||
<p>
|
||
However, you have to look for changes over time yourself by tracking what's happening in the
|
||
graph.
|
||
</p>
|
||
|
||
<p>
|
||
The HPROF Analyzer finds the following potential issues:
|
||
</p>
|
||
|
||
<ul>
|
||
<li>All destroyed activity instances that are reachable from garbage collection roots.
|
||
</li>
|
||
|
||
<li>Where the target program has strings that repeat values.
|
||
</li>
|
||
</ul>
|
||
|
||
<p>
|
||
A dominator is at the top of a tree. If you remove it, you also remove the branches of the tree
|
||
it dominates, so it’s a potential way to free memory.
|
||
</p>
|
||
|
||
<h3 id="hprof-snapshot">
|
||
Taking and displaying a snapshot of the Java heap
|
||
</h3>
|
||
|
||
<p>
|
||
To see a snapshot of the Java heap, follow these steps:
|
||
</p>
|
||
|
||
<ol>
|
||
<li>While the Memory Monitor is running, click Dump Java Heap
|
||
<img src="{@docRoot}images/tools/am-idump.png"
|
||
style="vertical-align:sub;margin:0;height:17px" alt="Dump Java Heap icon" />.
|
||
</li>
|
||
|
||
|
||
<p>
|
||
When the icon on the Memory Monitor display changes from
|
||
<img src="{@docRoot}images/tools/am-idumpstart.png"
|
||
style="vertical-align:sub;margin:0;height:17px" alt="Dump Java Heap Start icon" /> to
|
||
<img src="{@docRoot}images/tools/am-idumpend.png" style="vertical-align:sub;margin:0;height:17px"
|
||
alt="Dump Java Heap End icon" />, the file is ready. Android Studio creates the heap snapshot
|
||
file with the
|
||
filename <code>Snapshot_<em>yyyy.mm.dd_hh.mm.ss</em>.hprof</code> using
|
||
the year, month, day, hour, minute, and second of the capture, for example,
|
||
<code>Snapshot_2015.11.17_14.58.48.hprof</code>.
|
||
</p>
|
||
|
||
<li>Click <strong>Captures</strong> in the main window.
|
||
</li>
|
||
|
||
<p>
|
||
The <em>Captures</em> window appears.
|
||
</p>
|
||
|
||
<li>Double-click the file to view it in the HPROF Viewer.
|
||
</li>
|
||
|
||
<p>
|
||
The HPROF Viewer appears:
|
||
</p>
|
||
<img src="{@docRoot}images/tools/am-hprofviewer.png" />
|
||
<p>
|
||
The tool displays the following information:
|
||
</p>
|
||
|
||
<table>
|
||
<tr>
|
||
<th scope="col">Column</th>
|
||
<th scope="col">Description</th>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td><strong>Class Name</strong></td>
|
||
<td>The Java class responsible for the memory.</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td><strong>Total Count</strong></td>
|
||
<td>Total number of instances outstanding.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Heap Count</strong></td>
|
||
<td>Number of instances in the selected heap.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Sizeof</strong></td>
|
||
<td>Size of the instances (currently, 0 if the size is variable).</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Shallow Size</strong></td>
|
||
<td>Total size of all instances in this heap.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Retained Size</strong></td>
|
||
<td>Size of memory that all instances of this class is dominating.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Instance</strong></td>
|
||
<td>A specific instance of the class.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Reference Tree</strong></td>
|
||
<td>References that point to the selected instance, as well as references pointing to the
|
||
references.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Depth</strong></td>
|
||
<td>The shortest number of hops from any GC root to the selected instance.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Shallow Size</strong></td>
|
||
<td>Size of this instance.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Dominating Size</strong></td>
|
||
<td>Size of memory that this instance is dominating.</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<li>Select the Heap menu option you want to display:
|
||
<ul>
|
||
<li>
|
||
<strong>App heap</strong> - The heap used by the current app.
|
||
</li>
|
||
|
||
<li><strong>Image heap</strong> - The memory mapped copy of the
|
||
current app on disk.
|
||
</li>
|
||
|
||
|
||
<li>
|
||
<strong>Zygote heap</strong> - The common set of libraries and runtime classes and data that
|
||
all apps are forked
|
||
from. The zygote space is created during device startup and is never allocated into.
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
<li>Select the View menu option you want to display:
|
||
<ul>
|
||
<li>
|
||
<strong>Class List View</strong>
|
||
</li>
|
||
|
||
<li>
|
||
<strong>Package Tree View</strong>
|
||
</li>
|
||
</ul>
|
||
</ol>
|
||
|
||
|
||
<h3 id="hprof-diving">
|
||
Diving into heap dump data in the HPROF Viewer
|
||
</h3>
|
||
<p>The following steps outline the typical workflow:</p>
|
||
<ol>
|
||
<li>In the HPROF viewer, select a class name. </li>
|
||
<li>Select an instance of that class.</li>
|
||
<li>Examine the reference tree.</li>
|
||
<li>Right-click an item to <strong>Jump to source</strong> or <strong>Go to instance</strong>,
|
||
as needed.</li>
|
||
</ol>
|
||
|
||
|
||
|
||
<h3 id="hprof-analyzing">Analyzing heap dump data in the HPROF Analyzer</h3>
|
||
<p>You can detect leaked activities and find duplicate strings with the HPROF Analyzer.
|
||
Follow these steps: </p>
|
||
<ol>
|
||
<li>In the <em>Captures</em> window, double-click an <code>.hprof</code> file to display it in the
|
||
HPROF Viewer. </li>
|
||
<li>Click <strong>Capture Analysis</strong> on the right side of the main Android Studio window.</li>
|
||
|
||
|
||
<p>The HPROF Analyzer appears to the right of the HPROF Analyzer, by default: </p>
|
||
|
||
<img src="{@docRoot}images/tools/am-hprofanalyzer.png" />
|
||
|
||
<li>In the <strong>Analyzer Tasks</strong> list, select the items you want to find.</li>
|
||
<li>Click Perform Analysis <img src="{@docRoot}images/tools/am-iperformanalysis.png"
|
||
style="vertical-align:sub;margin:0;height:17px" alt="Perform Analysis icon" />.</li>
|
||
<li>Examine the items in <strong>Analysis Results</strong>. Click an item to display it in the
|
||
HPROF Viewer.</li>
|
||
</ol>
|
||
|
||
|
||
|
||
<h3 id="hprof-sorting">Sorting heap dump data</h3>
|
||
<p>Follow this step:</p>
|
||
<ul>
|
||
<li>In the HPROF Viewer, click a column heading to sort the table by ascending or descending
|
||
order. </li>
|
||
</ul>
|
||
|
||
|
||
<h3 id="hprof-source">Displaying Java source</h3>
|
||
<p>For some items displayed in the HPROF Viewer, you can go straight to its source code.
|
||
Follow this step:</p>
|
||
<ul>
|
||
<li>In the HPROF Viewer, right-click a class, instance, or item in the reference tree, and then
|
||
select <strong>Jump to Source</strong>. </li>
|
||
|
||
|
||
<p>The source code appears in the Code Editor.</p>
|
||
</ul>
|
||
|
||
<h3 id="hprof-viewing">Viewing a saved HPROF file</h3>
|
||
<p>After you do a heap dump, Android Studio automatically stores it so you can view it again.
|
||
Follow these steps:</p>
|
||
|
||
<ol>
|
||
<li>Click <strong>Captures</strong> in the main window.</li>
|
||
|
||
<p>The <em>Captures</em> window appears.</p>
|
||
<li>Open the <strong>Heap Snapshot</strong> folder.</li>
|
||
<li>Double-click the file to view it.</li>
|
||
</ol>
|
||
|
||
|
||
<h3 id="hprof-renaming">Renaming an HPROF file</h3>
|
||
|
||
<p>If you rename a file from within Android Studio, it continues to appear in <em>Captures</em>
|
||
window. Follow these steps:</p>
|
||
<ol>
|
||
<li>In the <em>Captures</em> window, right-click the file and select <strong>Rename</strong>. </li>
|
||
<li>In the dialog, specify the name of the file and click <strong>OK</strong>.</li>
|
||
</ol>
|
||
|
||
|
||
<h3 id="hprof-locating">Locating a heap dump file on disk</h3>
|
||
<p>You can quickly discover where Android Studio stored HPROF files on disk.</p>
|
||
|
||
|
||
<p>Follow this step in Android Studio: </p>
|
||
<ul>
|
||
<li>In the <em>Captures</em> window, right-click a heap snapshot file and select
|
||
<strong>Show in files</strong>.</li>
|
||
|
||
<p>Android Studio opens an operating system file browser displaying the location where the file
|
||
resides.</p>
|
||
</ul>
|
||
<p class="note"><strong>Note:</strong> If you move an HPROF file, Android Studio no longer
|
||
displays it in the <em>Captures</em> window. To display it, use
|
||
<strong>File</strong> > <strong>Open</strong>. Also, if you want to rename the file, do it
|
||
from the <em>Captures</em> window and not in the operating system file browser. </p>
|
||
|
||
<h3 id="hprof-deleting">Deleting a heap dump file</h3>
|
||
|
||
<p>To delete a heap dump file, follow this step: </p>
|
||
<ul>
|
||
<li>In the <em>Captures</em> window, right-click a heap snapshot file and select
|
||
<strong>Delete</strong>.</li>
|
||
|
||
<p>Android Studio deletes the file from the <em>Captures</em> dialog and from disk. </p>
|
||
</ul>
|
||
|
||
<h3 id="hprof-converting">Converting a heap dump file to standard HPROF format</h3>
|
||
<p>You can convert an HPROF file to standard format so you can use it outside of Android Studio with
|
||
other analysis tools. Follow these steps: </p>
|
||
<ol>
|
||
<li>In the <em>Captures</em> window, right-click a heap snapshot file and select <strong>Export to
|
||
standard .hprof</strong>.</li>
|
||
<li>In the <em>Convert Android Java Heap Dump</em> dialog, specify a filename and click
|
||
<strong>OK</strong>.</li>
|
||
|
||
|
||
<p>Android Studio creates a binary HPROF file in the location you specified.</p>
|
||
</ol>
|
||
|
||
<h2 id="tracking">
|
||
Tracking and Analyzing Memory Allocation
|
||
</h2>
|
||
|
||
<p>Android Studio allows you to track memory allocation as it monitors memory use. Tracking memory
|
||
allocation allows you to monitor where objects are being allocated when you perform certain
|
||
actions. Knowing these allocations enables you to adjust the method calls related to those actions
|
||
to optimize app performance and memory use.</p>
|
||
|
||
<p>The Allocation Tracker does the following:</p>
|
||
<ul>
|
||
<li>Shows when and where your code allocates object types, their size, allocating thread, and stack
|
||
traces.</li>
|
||
<li>Helps recognize memory churn through recurring allocation/deallocation patterns.</li>
|
||
<li>Help you track down memory leaks when used in combination with the HPROF Viewer. For example,
|
||
if you see a bitmap object resident on the heap, you can find its allocation location with
|
||
Allocation Tracker.</li>
|
||
</ul>
|
||
|
||
|
||
<p>However, it takes time and experience to learn to interpret the output from this tool.</p>
|
||
|
||
<h3 id="alloc-snapshot">Taking and displaying a snapshot of allocation data</h3>
|
||
|
||
<p>Follow these steps:</p>
|
||
<ol>
|
||
<li>While the Memory Monitor is running, click Start Allocation Tracking
|
||
<img src="{@docRoot}images/tools/am-ialloctracking.png"
|
||
style="vertical-align:sub;margin:0;height:17px" alt="Start Allocation Tracking icon" />. </li>
|
||
<li>Click Start Allocation Tracking
|
||
<img src="{@docRoot}images/tools/am-ialloctracking.png"
|
||
style="vertical-align:sub;margin:0;height:17px" alt="Start Allocation Tracking icon" /> again to
|
||
deselect it and end the snapshot. </li>
|
||
|
||
<p>The Memory Monitor displays the period when it took the snapshot. In the following
|
||
figure, you can see the snapshot period, as shown on the left. By comparison, when you dump the
|
||
Java heap, the Memory Monitor displays just the point where the heap snapshot was taken, as
|
||
shown on the right.</p>
|
||
<img src="{@docRoot}images/tools/am-dumpalloc.png" />
|
||
|
||
<p>Android Studio creates the heap snapshot file with the
|
||
filename <code>Allocations_<em>yyyy.mm.dd_hh.mm.ss</em>.alloc</code> using the year, month, day,
|
||
hour, minute, and second of the capture, for example,
|
||
<code>Allocations_2015.11.17_14.58.48.alloc</code>.</p>
|
||
<li>Click <strong>Captures</strong> in the main window.</li>
|
||
|
||
|
||
<p>The <em>Captures</em> window appears.</p>
|
||
<li>Double-click the file to view it in the Allocation Tracker. </li>
|
||
<li>Optionally click the graphic icon to display a visual representation of the data.
|
||
</li>
|
||
<p>
|
||
The Allocation Tracker appears:
|
||
</p>
|
||
<img src="{@docRoot}images/tools/am-alloctracker.png" />
|
||
<p>
|
||
|
||
|
||
<p>The tool displays the following information: </p>
|
||
|
||
<table>
|
||
<tr>
|
||
<th scope="col">Column</th>
|
||
<th scope="col">Description</th>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td><strong>Method</strong></td>
|
||
<td>The Java method responsible for the allocation.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Count</strong></td>
|
||
<td>Total number of instances allocated.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Size</strong></td>
|
||
<td>The total amount of allocated memory in bytes.</td>
|
||
</tr>
|
||
|
||
</table>
|
||
|
||
|
||
<li>Select the Group By menu option you want to display: </li>
|
||
<ul>
|
||
<li><strong>Group by Allocator</strong> </li>
|
||
<li><strong>Group by Method</strong></li>
|
||
</ul>
|
||
|
||
</ol>
|
||
|
||
|
||
|
||
<h3 id="alloc-sorting">Sorting allocation data</h3>
|
||
|
||
<p>Follow this step:</p>
|
||
<ul>
|
||
<li>In the Allocation Tracker, click a column heading to sort the table by ascending or
|
||
descending order. </li>
|
||
</ul>
|
||
|
||
|
||
<h3 id="alloc-source">Displaying Java source</h3>
|
||
<p>For some items displayed in the Allocation Tracker, you can view the Java source. Follow one of
|
||
these steps:</p>
|
||
<ul>
|
||
<li>In the Allocation Tracker, right-click a method and then select <strong>Jump to Source</strong>.
|
||
</li>
|
||
<li>In the Allocation Tracker, select a method and then click Jump to Source
|
||
<img src="{@docRoot}images/tools/am-ijumptosource.png"
|
||
style="vertical-align:sub;margin:0;height:17px" alt="Jump to Source icon" />. </li>
|
||
</ul>
|
||
|
||
<p>The source code appears in the Code Editor.</p>
|
||
|
||
<h3 id="alloc-viewing">Viewing a saved allocation tracking file</h3>
|
||
<p>After you monitor allocation tracking, Android Studio automatically stores it so you can view it
|
||
again. Follow these steps:</p>
|
||
|
||
|
||
<ol>
|
||
<li>Click <strong>Captures</strong> in the main window.</li>
|
||
|
||
|
||
<p>The <em>Captures</em> window appears.</p>
|
||
<li>Open the <strong>Allocation Tracking</strong> folder.</li>
|
||
<li>Double-click the file to view it.</li>
|
||
</ol>
|
||
|
||
|
||
<h3 id="alloc-renaming">Renaming an allocation tracking file</h3>
|
||
|
||
<p>If you rename a file from within Android Studio, it continues to appear in the <em>Captures</em>
|
||
window. Follow these steps:</p>
|
||
<ol>
|
||
<li>In the <em>Captures</em> window, right-click the file and select <strong>Rename</strong>.</li>
|
||
<li>In the <em>Rename</em> dialog, specify the name of the file and click <strong>OK</strong>.</li>
|
||
</ol>
|
||
|
||
|
||
<h3 id="alloc-locating">Locating an allocation tracking file</h3>
|
||
<p>You can quickly discover where Android Studio stored allocation tracking files on disk.</p>
|
||
|
||
|
||
<p>Follow this step in Android Studio: </p>
|
||
<ul>
|
||
<li>In the <em>Captures</em> window, right-click allocation file and select
|
||
<strong>Show in Files</strong>.</li>
|
||
|
||
<p>Android Studio opens an operating system file browser displaying the location where the file
|
||
resides.</p>
|
||
</ul>
|
||
|
||
<p class="note"><strong>Note:</strong> If you move an allocation tracking file, Android Studio
|
||
no longer displays it in the <em>Captures</em> window. To display the file, use
|
||
<strong>File</strong>
|
||
> <strong>Open</strong>. Also, rename the file from the <em>Captures</em>
|
||
window and not in the operating system file browser. </p>
|
||
|
||
<h3 id="alloc-deleting">Deleting an allocation tracking file</h3>
|
||
|
||
|
||
<p>Follow this step: </p>
|
||
<ul>
|
||
<li>In the <em>Captures</em> window, right-click an allocation tracking file and select
|
||
<strong>Delete</strong>.</li>
|
||
|
||
<p>Android Studio deletes the file from the <em>Captures</em> dialog and from disk. </p>
|
||
</ul>
|