Recently, I reviewed the performance optimization of Android system. Writing a blog is to learn and record, I hope to help other students while recording. Recently I thought I’d come up with a series of don ‘ts. “Don’t know how to hit me.” “Don’t know how to cut me.” “Don’t know how to punch me.”

Profiler analysis of memory jitter

In our development projects, memory jitter often occurs if we are not careful. And some memory jitter may also cause our program to stall, or even leak. Next, use the Profiler that comes with Android Studio to analyze memory jitter.


1.1. Simulate memory jitter and open Profiler

First create a memory jitter code in MainActivity:

private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            // Create memory jitter
            for (int i = 0; i < 100; i++) {
                String arg[] = new String[100000];
            }
            mHandler.sendEmptyMessageDelayed(0.30); }};Copy the code



After running, the following image appears,




1.2. Analyze memory jitter

Click on the button, trigger memory jitter code, to see our memory condition, you can see the zigzag


Click record in the red box above, and then click Stop to analyze a section of our jagged shape, as shown in the picture:

Allocations: indicates what was allocated. Shallow Size: indicates current memory usage

If you left click String[], all strings [] will appear on the right side. Then click any of them to display the Allocation Call Stack information:

Can see clearly in our code, because handleMessage: 21, MainActivity $1 (com. Leo. Memoryanalyzertest), caused by the jitter of memory. Right click on this and Jump to Source. To Jump to our problem code. This is where our Profiler analyzes memory jitter.


1.3. If you use the traceView method, that is, the CPU Profiler method

First of all, let’s speculate that traceView is an analytical caton tool, and of course it can be measured here. But it’s biased towards the time consuming case. As I said in the last post, I won’t make it clear here. Also click CPU, then record, stop record a section. The picture comes to our Top Down:

Can see long time in the MessageQueue, this also is associated with our memory jitter code, send a 30 ms intervals, the handleMessage (), and pointed out the code in com. Leo. Memoryanalyzertest. MainActivity. You can see that this way to analyze, it’s not obvious.

Note: We all know about memory jitter, and if we’re looking for it, it’s where we’re looking for loops or frequent calls. So we can use CPU Profiler methods to roughly identify the location of the problem code.


Memory leaks are analyzed by Memory Analyzer

Again, let’s create a memory leak code and define an interface

public interface CallBack {
    void leoFun(a);
}
Copy the code


Then create a static list and add the CallBack instance

public class CallBackManager {
    public static ArrayList<CallBack> sCallBacks = new ArrayList<>();

    public static void addCallBack(CallBack callBack) {
        sCallBacks.add(callBack);
    }

    public static void removeCallBack(Callback callback) { sCallBacks.remove(callback); }}Copy the code


Create a BitmapActivity CallBack interface, set a large image main_bg, and put the instance into a static sCallBacks. This will cause the BitmapActivity to be uncollected every time it starts and exits.

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bitmap);

        ImageView imageView = findViewById(R.id.image);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.main_bg);
        imageView.setImageBitmap(bitmap);
        CallBackManager.addCallBack(this);
    }
Copy the code


So we keep opening and closing the page and looking at the memory, as shown here, we can see that the memory goes up:

Red box 1: The function is to initiate an active GC. The purpose is to recycle some recyclable, virtual references, etc. Avoid memory analysis interference Red box 2: heap dump, convert memory allocation to hprof file. (Note that this is the Studio hprof file, and if you need to analyze it with Memory Analyzer, convert it to a standard hprof file)

Right-click Export to save the file in the folder.

Convert to the Hprof file that mat can recognize. As long as the CMD command line comes to the hprof-conv.exe file of our studio and enters the command, it can be converted

Hprof-conv source file path Output file path, thus generating our my.hprof


2.1. How do I use Our Memory Analyzer

After the hprof file is generated, Memory Analyzer is then used. Official website to download address: www.eclipse.org/mat/downloa… Because of the donation and so on, not recommended. I found a more reliable version here, CSDN download

Once downloaded, start our memoryAnalyzer.exe. File –> Open Heap Dump to Open our my.hprof File.

A brief introduction to Memory Analyzer information.

Red box 1: OverView information

  • Size Memory Size
  • Classes: class objects
  • Objects: The number of Objects, that is, the number of instances
  • Unreachable Objects Histogram: Objects that can be reclaimed and thrown into memory


2.1.2 red box 2: Histogram

  • Objects: How many instances of this class
  • Shallow Heap: The memory occupied by a single instance
  • Retained Heap: How much memory is Retained by a single instance and its references

We can use the Regex in the histogram to search for our original memory leak case. If you search for BitmapActivity, you can see that we have three instances of BitmapActivity:

We can right click on the com. Leo. Me, oryanalyzertest. BitmapActivity objects > List — – > with incoming reference (who quoted me), You can see that there are three places that reference BitmapActivity:

Right click on Path To GC Roots –> With All Refrence, as shown in the picture, To find the file with the little sun under the file, which may trigger memory overflow. This means that our sCallBacks reference it and confirms that it was added to the static collection sCallBacks in the CallBackManager in our memory leaking code.


2.1.3 red box 3: Dominator Tree shows the memory and proportion of each instance

You can see that our big head here is a Bitmap.

We can also see our sCallBacks reference by right-clicking an instance Path To GC Roots –> with all refrence:


2.1.4 red box 4: OQL, similar to the database searching our memory

After writing the command, click the red exclamation mark to run it, as shown


2.1.5 red box 5: Thread Overview, showing the status of threads


2.1.6, red box 6: Top Consumers (key), directly shows the large memory in our memory

To show how much memory we have in memory, we can see that there are three large bitmaps. Intuition is good for analysis


2.1.7. Red box 7: A Leak Suspects that we will directly analyze the places in our code where memory leaks might occur

Here I started the BitmapActivity three times, and it also gave me three analyses. Click on the details. Look at the details, also directly set the problem in sCallBacks:


My official account

Can send some plain words practical article. I’m always looking for the best interview techniques. Students with ideas can join