Android Studio之記憶體分析

weixin_33716557發表於2016-11-20

主要還是翻譯了,官方的,Android studio 使用,對比著Androidstudio,讓你馬上成為記憶體分析高手

Android Monitorprovides 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:

Android Monitor提供了一個記憶體監視器,以便您可以更輕鬆地監視應用程式效能和記憶體使用情況,以查詢釋放的物件,找到記憶體洩漏,並跟蹤連線的裝置使用的記憶體量。記憶體監視器報告應用程式如何分配記憶體,並幫助您視覺化應用程式使用的記憶體。它允許您:

Show a graph of available and allocated Java memory

over time.

Show garbage collection (GC) events over time.

Initiate garbage collection events.

Quickly test whether app slowness might be related to

excessive garbage collection events.

Quickly test whether app crashes may be related to

running out of memory.

顯示可用和分配的Java記憶體隨時間的圖表。

隨著時間的推移顯示垃圾收集(GC)事件。

啟動垃圾回收事件。

快速測試應用程式慢度是否可能與過多的垃圾回收事件相關。

快速測試應用程式當機是否與記憶體用完相關。

Memory Monitor Workflow記憶體監視器工作流

To profile and optimize memory use, the typical

workflow is to run your app and do the following:

Profile the app using the Memory

Monitor to find out whether undesirable garbage collection event patterns

might be causing performance problems.

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.

Start allocation tracking to determine where any

problems are happening in your code.

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:

Get a sense of how your app allocates and frees memory.

Identify memory leaks.

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:

Identify where many similar object types, from roughly

the same call stack, are allocated and deallocated over a very short

period of time.

Find the places in your code that may contribute to

inefficient memory use

要配置和優化記憶體使用,典型的工作流程是執行您的應用程式,並執行以下操作:

使用記憶體監視器配置應用程式,以確定不受歡迎的垃圾收集事件模式是否可能導致效能問題。

如果在很短的時間內看到很多垃圾收集事件,請轉儲Java堆以標識獲取或保持意外或不必要分配的候選物件型別。

開始分配跟蹤,以確定您的程式碼中發生了什麼問題。

Java堆資料實時顯示應用程式分配的物件型別,數量以及它們在堆上的大小。檢視堆有助於:

瞭解你的應用程式如何分配和釋放記憶體。

識別記憶體洩漏。

分配跟蹤記錄應用程式記憶體分配,並列出分析週期的所有分配,包括呼叫堆疊,大小和分配程式碼。它可以幫助您:

識別來自大致相同的呼叫棧的許多類似的物件型別在很短的時間內被分配和釋放。

找到程式碼中可能會導致低效記憶體使用的地方

Garbage collection roots and dominator trees

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

icon (and a depth of zero) and a dominator with

the

icon.

There are several kinds of garbage collection roots

in Java:

references on the stack

Java Native Interface (JNI) native objects and memory

static variables and functions

threads and objects that can be referenced

classes loaded by the bootstrap loader

finalizers and unfinalized objects

busy monitor objects

垃圾收集根和支配者樹

當轉儲Java堆時,記憶體監視器建立一個Android特定的堆/ CPU分析(HPROF)檔案,您可以在HPROF檢視器中檢視。HPROF檢視器指示具有GC根圖示圖示(深度為零)的垃圾回收根以及具有Dominator圖示圖示的控制器。

Java中有幾種垃圾回收根:

堆疊上的引用

Java本機介面(JNI)本機物件和記憶體

靜態變數和函式

執行緒和物件

由引導載入程式載入的類

終結者和未定義的物件

繁忙的監視器物件

The HPROF file provides the list of roots to the

HPROF Viewer.

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.


3587638-bf5df3f00a123ff7.png

HPROF檔案向HPROF檢視器提供根的列表。

控制樹跟蹤由應用程式建立的物件的路徑。

如果到達另一物件的唯一方式是直接或間接地通過控制器物件,則物件支配另一物件。 當您檢查應用程式建立的物件和路徑以優化記憶體使用時,請嘗試刪除不再需要的物件。

您可以釋放控制物件以釋放所有下級物件。 例如,在下圖中,如果您要刪除物件B,那麼也將釋放它所支配的物件(即物件C,D,E和F)使用的記憶體。實際上,如果物件C,D,E和F標記為移除,但物件B仍然指向它們,這可能是它們未釋放的原因。

Memory leak and use analysis

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.

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?

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.

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.

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.

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.

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.

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

記憶體洩漏和使用分析

如果應用程式有效地使用記憶體,應用程式的效能會更好,並且在不再需要記憶體時釋放記憶體。大的或隨時間增長的記憶體洩漏是最重要的糾正。

優化記憶體使用的一種方法是分析大型陣列。例如,你可以減少陣列中單個元素的大小以節省記憶體嗎?

另一個值得關注的領域是應用程式不再需要但繼續參考的物件。您可以在不同時間段收集堆轉儲,並比較它們以確定是否有不斷增長的記憶體洩漏,例如您的程式碼多次建立但不會銷燬的物件型別。例如,這些物件可以是增長陣列或物件樹的一部分。要跟蹤這個問題,比較堆轉儲,看看你是否有一個特定的物件型別繼續隨著時間的推移有越來越多的例項。

包含根或控制器物件的持續增長的物件樹可以防止從屬物件被垃圾回收。此問題是記憶體洩漏,記憶體不足錯誤和崩潰的常見原因。您的應用程式可能具有少量物件,這會阻止大量的下級物件被破壞,因此會快速耗盡記憶體。要找到這些問題,請獲取堆轉儲並檢查由根和控制器物件持有的記憶體量。如果記憶體很大,你可能會找到一個好的地方開始優化你的記憶體使用。

當您開始縮小記憶體問題時,您還應該使用分配跟蹤器來更好地瞭解分配記憶體分配物件的位置。分配跟蹤器可以是有價值的,不僅用於檢視記憶體的特定用途,而且用於分析關鍵程式碼路徑,例如載入和滾動。例如,在應用程式中顯示列表時跟蹤分配,您可以檢視需要為該行為完成的所有分配,它們所在的執行緒以及它們來自哪裡。這些資訊對於收緊這些路徑以減少他們需要的工作和改善UI的整體平滑性是非常有價值的。

對於不必要的分配或者多次建立相同物件而不是重用它們的分配來檢查演算法非常有用。例如,你是否在遞迴迴圈中建立臨時物件和變數?如果是這樣,請嘗試在迴圈之前建立一個物件或變數,以便在迴圈中使用。否則,您的應用程式可能會不必要地分配許多物件和變數,具體取決於遞迴的數量。

對於建立最大和最大物件的程式碼部分執行分配測試很重要,因為這些區域提供了最多的優化機會。除了單元測試,你應該測試你的應用程式與生產現實的資料載入,特別是那些演算法是資料驅動。此外,確保考慮應用程式快取和啟動階段,有時可能很慢;分配分析最好在該階段後完成,以產生準確的結果。

優化程式碼後,請確保測試它的工作。您需要在不同的負載條件下測試,而且不需要執行記憶體監視器工具。比較優化前後的結果,以確保效能實際上有所提高

Memory management for different virtual machines

Android Monitor uses the Virtual Machine (VM) that

the device or emulator uses:

Android 4.3 (API level 18) and lower uses the Dalvik

VM.

In Android 4.4 (API level 19), the Android RunTime

(ART) VM is an option, while the Dalvik VM is the default.

Android 5.0 (API level 21) and higher uses the ART VM.

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.

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.

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.

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, seeAddressing Garbage Collection (GC) IssuesandInvestigating Your RAM Usage.

The ART VM adds a number of performance, development,

and debugging improvements over the Dalvik VM. For more information, seeART and Dalvik.

Memory management for different virtual machines

Android Monitor uses the Virtual Machine (VM) that

the device or emulator uses:

Android 4.3 (API level 18) and lower uses the Dalvik

VM.

In Android 4.4 (API level 19), the Android RunTime

(ART) VM is an option, while the Dalvik VM is the default.

Android 5.0 (API level 21) and higher uses the ART VM.

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.

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.

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.

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, seeAddressing Garbage Collection (GC) IssuesandInvestigating Your RAM Usage.

The ART VM adds a number of performance, development,

and debugging improvements over the Dalvik VM. For more information, seeART and Dalvik.

記憶體洩漏和使用分析

如果應用程式有效地使用記憶體,應用程式的效能會更好,並且在不再需要記憶體時釋放記憶體。大的或隨時間增長的記憶體洩漏是最重要的糾正。

優化記憶體使用的一種方法是分析大型陣列。例如,你可以減少陣列中單個元素的大小以節省記憶體嗎?

另一個值得關注的領域是應用程式不再需要但繼續參考的物件。您可以在不同時間段收集堆轉儲,並比較它們以確定是否有不斷增長的記憶體洩漏,例如您的程式碼多次建立但不會銷燬的物件型別。例如,這些物件可以是增長陣列或物件樹的一部分。要跟蹤這個問題,比較堆轉儲,看看你是否有一個特定的物件型別繼續隨著時間的推移有越來越多的例項。

包含根或控制器物件的持續增長的物件樹可以防止從屬物件被垃圾回收。此問題是記憶體洩漏,記憶體不足錯誤和崩潰的常見原因。您的應用程式可能具有少量物件,這會阻止大量的下級物件被破壞,因此會快速耗盡記憶體。要找到這些問題,請獲取堆轉儲並檢查由根和控制器物件持有的記憶體量。如果記憶體很大,你可能會找到一個好的地方開始優化你的記憶體使用。

當您開始縮小記憶體問題時,您還應該使用分配跟蹤器來更好地瞭解分配記憶體分配物件的位置。分配跟蹤器可以是有價值的,不僅用於檢視記憶體的特定用途,而且用於分析關鍵程式碼路徑,例如載入和滾動。例如,在應用程式中顯示列表時跟蹤分配,您可以檢視需要為該行為完成的所有分配,它們所在的執行緒以及它們來自哪裡。這些資訊對於收緊這些路徑以減少他們需要的工作和改善UI的整體平滑性是非常有價值的。

對於不必要的分配或者多次建立相同物件而不是重用它們的分配來檢查演算法非常有用。例如,你是否在遞迴迴圈中建立臨時物件和變數?如果是這樣,請嘗試在迴圈之前建立一個物件或變數,以便在迴圈中使用。否則,您的應用程式可能會不必要地分配許多物件和變數,具體取決於遞迴的數量。

對於建立最大和最大物件的程式碼部分執行分配測試很重要,因為這些區域提供了最多的優化機會。除了單元測試,你應該測試你的應用程式與生產現實的資料載入,特別是那些演算法是資料驅動。此外,確保考慮應用程式快取和啟動階段,有時可能很慢;分配分析最好在該階段後完成,以產生準確的結果。

優化程式碼後,請確保測試它的工作。您需要在不同的負載條件下測試,而且不需要執行記憶體監視器工具。比較優化前後的結果,以確保效能實際上有所提高

Displaying a Running App in the Memory Monitor

To display an app running on a particular device or

emulator in the Memory Monitor:

Meet theprerequisites and dependencies.

Open an app project.

Run the appon a hardware

device or emulator.

Display

Android Monitor.

Click theMonitorstab anddisplay the Memory Monitor.

Enable the Memory Monitor by clicking Pause

to deselect it.

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.

To force a garbage collection event, click Initiate

GC

.

In the following figure, the VM initiated the first

garbage collection event, while the developer forced the second.


3587638-8e1780ddebc34295.png

在記憶體監視器中顯示正在執行的應用程式

要在記憶體監視器中顯示在特定裝置或模擬器上執行的應用程式:

滿足先決條件和依賴關係。

開啟應用程式專案。

在硬體裝置或模擬器上執行應用程式。

顯示Android監視器。

單擊監視器選項卡並顯示記憶體監視器。

通過單擊暫停暫停圖示來取消選擇記憶體監視器。

在圖中,y軸以兆位元組顯示空閒和分配的RAM。x軸表示經過的時間;它以秒,然後是分鐘和秒開始,以此類推。

可用記憶體量(以兆位元組為單位)以淺色顯示,分配的記憶體為較暗的顏色。 當分配的記憶體急劇下降時,這表示垃圾回收事件。

要強制垃圾回收事件,請單擊啟動GC啟動GC圖示。

在下圖中,VM啟動了第一次垃圾收集事件,而開發人員強制第二次。

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're healthy

and what you expect.

The graph can show you potential issues:

Excessive garbage collection events slow down the app.

The app runs out of memory, which causes it to crash.

Potential memory leaks.

For example, you might see the following signs of

problems:

Your app is static, but you see memory being allocated

in the monitor.

You see spikes of memory allocations in the monitor,

but you don’t think there’s any app logic to cause this behavior.

To stop the Memory Monitor, click

Pause

again to select it.

Forcing a Garbage Collection Event

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.

To force a garbage collection event:

While theMemory

Monitor is running, click Initiate GC

與您的應用程式互動,並觀察它如何影響記憶體監視器中的記憶體使用情況。您可以識別應用程式的垃圾回收模式,並確定它們是否健康,以及您期望的內容。

該圖表可以顯示潛在問題:

過多的垃圾收集事件會減緩應用程式。

應用程式記憶體不足,導致它崩潰。

潛在記憶體洩漏。

例如,您可能會看到以下問題的跡象:

您的應用程式是靜態的,但您會看到在顯示器中分配的記憶體。

您會看到顯示器中的記憶體分配峰值,但您不認為有任何應用程式邏輯導致此行為。

要停止記憶體監視器,請再次單擊暫停暫停圖示以將其選中。

強制垃圾收集事件

通常,VM僅在絕對需要時執行垃圾收集,因為它很昂貴。然而,在某些情況下強制垃圾收集是有用的。例如,當定位記憶體洩漏時,如果要確定是否已成功釋放大物件,則可以比通常更積極地啟動垃圾回收。

強制垃圾收集事件:

當記憶體監視器執行時,單擊啟動GC啟動GC圖示

Taking a Snapshot of the Java Heap and Memory

Allocation

You can take snapshots while the Memory Monitor is

running or paused:

To take and display a snapshot of the Java heap,

seeHPROF Viewer

and Analyzer.

To take and display a snapshot of memory allocation,

seeAllocation

Tracker.

獲取Java堆和記憶體分配的快照

您可以在記憶體監視器執行或暫停時拍攝快照:

要獲取和顯示Java堆的快照,請參閱HPROF Viewer和Analyzer。

要獲取和顯示記憶體分配的快照,請參閱分配跟蹤器。

相關文章