Some of the theoretical aspects of performance optimization, mainly to review, with the theory, Comrade Xiaoping said again, practice is the only standard to test the truth, for memory leaks, now through the Android Studio self-brought tool memory monitor detected. The importance of performance optimization does not need to be stressed, but to emphasize that I am not an old driver, hey! Please open your eyes if you have not used this tool. If you have used it, then you don't have to read this blog.
Take a look at a memory leak of code first
public class UserManger {
private static UserManger instance;
private Context context;
private UserManger(Context context) {
this.context = context;
}
public static UserManger getInstance(Context context) {
if (instance == null) {
instance = new UserManger(context);
}
return instance;
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
UserManger userManger = UserManger.getInstance(this);
}
}
The code is very simple, is a simple interest pattern leaked scene, we are not concerned about the code itself, but how to leak the memory inside the code to find out. But there is a need to mention the reason for the memory leak in the code above.
The previous blog said that the reason for the memory leak is that when an object is no longer needed, it should be recycled, and another object that is being used holds its reference, causing the object to not be recycled. This resulted in a memory leak when the object that was supposed to be recycled could not be recycled and stuck in the heap memory.
In the above code, the leak is not usermanger, but a static member instance in the Mainactivity,usermanger, whose life cycle is consistent with the application's life cycle and can only be destroyed when exiting the application. But when the GC is ready to recycle mainactivity, the result is that the Mainactivity object (this) is referenced by Usermanger, and Usermanger itself cannot be killed, so a memory leak occurs.
Monitors.png
Memory monitor is a kind of Android monitors, monitors mainly includes four kinds, memory monitor, CPU Monitor, NetWork Monitor, GPU Monitor, Today is the memory monitor, the other monitor, is also ready to talk at the back.
Memory Monitor.png
- The horizontal direction of the graph is the timeline, and the vertical direction is the allocation of memory.
- The dark blue area of the figure, which represents the total amount of memory currently in use, a light blue or light gray area, indicating free memory or called unallocated memory.
- The Memory Analysis toolbar, from top to bottom, has a total of 4 buttons, followed by:
-
Stop detection switch, no real effect
is to manually invoke the GC, we must manually click the Initiate GC button to manually trigger the GC before grasping the memory, so that the captured memory usage does not include the Unreachable object (unreachable refers to objects that can be reclaimed by the garbage collector. But because there is no GC, so there is no release, then the memory used in the capture of the unreachable is these objects)
(Dump Java Heap) Click to generate a file ( package name + Date + ". Hprof") that can be recorded to touch a point in time, program memory situation. Get hprof file (hprof file is the file we use when we use the Mat tool to analyze memory), but the file mat directly generated here is not directly available and needs to be converted into a standard hprof file. can be converted using Androidstudio or HPROF-CONV command, online can be found
Start distribution tracking, first click to specify where to start tracking memory, and the second click to end the tracking location. So we intercept a section of memory to be analyzed, wait a few seconds Androidstudio will open a allocation view for us (feel the same as the Mat tool, but the mat tool is more powerful, we can also get the Hprof file, using mat to analyze)
Go back to our program and click the GC several times to see the memory usage of this app.
Memory usage. jpg
You can see that the memory allocated now has 19.68M, I rotate the phone a bit, look.
Memory usage after rotation. png
Can see the current memory usage is 21.09M, or the same interface, but more than 1.41M!!! This is key.
Next, let's find out where the leak happened. Click Dump Java Heap to generate the snapshot file Tool.test.memory.memoryleak_2016.11.13_21.38.hprof,android Studio automatically pops up hprof viewer to analyze it.
Snapshot file analysis. png
Now introduce the usage of the Hprof Viewer
- HPROF Viewer View mode
The upper-left corner of the two red boxes, is an optional list, is used to select the heap area, and the way Class View is displayed.
The heap types are divided into:
App Heap-The heap used by the current app
Image Heap-A memory-mapped copy of the current app on disk
Zygote Heap-The Zygote process heap (each app process is hatched from Zygote, which is basically the heap of generic classes in the framework)
Class List View--the way the classes are listed
Package tree view-based on the tree-like display of the packet structure
I usually click on the classs name below the app heap to sort all the classes in the heap alphabetically, and then look in alphabetical order.
- HPROF Viewer Main sub-ABC three major plates
Plate A: Names of all classes in this application
Section B: All instances of the left class
Plate C: After selecting an instance in B, the reference tree for this instance
- The upper left corner of a plate is explained in column name
Column Name |
explain |
Class Name |
Class name, all class in the heap |
Total Count |
In memory, the total number of objects in this class, some in the stack, some in the heap |
Heap Count |
The number of such objects in the heap memory |
Sizeof |
The amount of memory that each instance occupies |
Shallow Size |
The amount of memory consumed by all instances of this class |
Retained Size |
How much memory will be freed when all such objects are freed |
- The upper right corner of the B plate is explained in column name
Column Name |
explain |
Instance |
Instances of this class |
Depth |
Depth, from any GC root point to the minimum hop count of the instance |
Dominating Size |
The amount of memory the instance can dictate |
There is a "button in the upper right corner of the B plate, which will enter the analysis interface of Hprof Analyzer's hprof:
Analyzer Tasks.png
Click the green run arrow on the right side of the analyzer tasks, and Android Studio will automatically analyze which classes have memory leaks based on this hprof file, as shown in:
Here's an analysis of Mainactivity's leaks.
Mainactivity a memory leak occurs. PNG in this interface can directly find out the memory leaks possible classes.
- An activity should have only one instance, but judging from the a area, total count has a value of 2,heap count and also 2, indicating that one is superfluous.
- You can see two instances of mainactivity in the B area, click on a reference tree to see his case
- In the C zone, you can see that the instance of Mainactivity is referenced by the Usermanger instance, with a reference depth of 1.
- In the analyzer Tasks area, tell you directly that leaked activities,mainactivity contains
There's a lot of evidence that mainactivity a memory leak.
Solution Solutions
public class UserManger {
private static UserManger instance;
private Context context;
private UserManger(Context context) {
this.context = context;
}
public static UserManger getInstance(Context context) {
if (instance == null) {
if(context!=null){
instance = new UserManger(context.getApplicationContext());
}
}
return instance;
}
}
Do not use the activity context, because the activity can be recycled at any time, we use the application Context,application context life cycle is the entire application, does not recycle also has no relation.
Memory Monitor gets a dynamic view of the RAM, and the heap viewer shows what's stored in the heap memory, but the heap viewer doesn't show where your data is assigned to the code, and if it's not, you want to know exactly what code is using the memory. Another feature is the allocation Tracker, which is used for memory allocation tracking. Click on the red part of the memory map, start the tracking, click again to stop tracking, and then automatically generate a Alloc end of the file, this file will record all the data tracked, and then open a data panel in the upper right corner
Allocation Tracker Start tracking
Allocation tracker boot trace. png
,
Allocation Tracker View mode
Allocation Tracker View mode
There are two ways of viewing, by default group by method
- Group by method: Using methods to classify our memory allocations
- Group by Allocator: Using a memory allocator to classify our memory allocations
As you can see, the thread object is first categorized, size is the amount of memory, count is how many times the memory is allocated, and clicking on the thread will see how all the memory is allocated in each thread
-Fan Chart
[Email protected]_1 ' [email protected]%s%6.png
Click the Chart button, will be generated, sector chart is the starting point of the circle, the outermost is its memory of the actual allocation of objects, each concentric circle may be divided into multiple parts, representing its different descendants, each concentric circle represents one of his descendants, each part of the division represents a number of people, When you double-click a split part of a concentric circle, it becomes the center of the generation that you clicked and then expands outward.
The problems that Memory Monitor can find
The Memory Monitor tool is a monitoring tool, a discovery type or a monitoring tool, such as a doctor's four skills [palpation],[] is the first step. The memory monitor here is a kind of [look] tool, I mainly use it to look at the following a number of problems:
1. Scenarios where memory jitter is found
2. Discover scenarios where large memory objects are allocated
3. Discover the growing memory scene
4. Determine if the lag problem is due to a GC operation
Case analysis
The first paragraph of the above indicator shows that the memory suddenly increased by 7M, we can see very clearly, so this point we have to locate the problem where, is bitmap or what cause, the second paragraph mark is memory jitter, it is obvious in a very short time the memory allocation and release of multiple times. And in the event of memory jitter, you can also feel the app's lag, can be seen as a result of performing a GC operation.
The constant increase in memory is easy to see by using Memory Monitor, and the blue curve is all the way up, and it's a sight to know.
Android memory Optimizer 1 Memory Detection Tool 1 Memory monitor detects a leak