The origin of

Memory jitter is caused by a large number of objects moving in and out of the nascent area in a short period of time, and it is accompanied by frequent GC. Gc consumes a lot of UI threads and CPU resources, which can cause the app to stall

The android Profile effect is shown below

The Memory of

We can see the rows of white trash cans above. Indicates that a large number of GC operations are performed. After a while the phone started to jam

Learning content

  • The Android Studio 3.0 compiler looks at memory jitter
  • Use tools to quickly locate code causing memory jitter.
  • Learn what errors can cause memory problems and how to avoid them.

Quickly locate memory jitter

Fast location also requires DDMS. Android Device Monitor ->Android Device Monitor

Then we look at the picture below.

Don’t panic.

The red box in the middle is what we want to analyze, look at his uneven is caused by memory jitter.

And then we’re going to zoom in on the red box. Click and drag the mouse to the right, it will become larger, click on the red box above the number will become smaller.

Let’s zoom in on the jitter. Click randomly and the following style will appear

You can see the pattern of this pink arch. Going from the left to the right represents how long a function takes.

Let’s quickly figure out where the problem code is

I just randomly swiped and randomly selected one, and then below that I show the method that I selected.

Here’s a detail

  • The ordinal number at the beginning of onClick is 9
  • The method sequence number under Parent is 8
  • The method sequence number under children is 10

The sequence number of onClick is greater than that of the method called by onClick. Less than the ordinal number of the method onClick is calling.

If we keep clicking on the method under Parent, we’ll find the method with the number 1

As shown in the figure below.

We found the error code. So let’s take a look at the source code


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { imPrettySureSortingIsFree(); }}); } /** *   After sorting, print a two-dimensional array, one line at a time. Print */ public voidimPrettySureSortingIsFree() {
        int dimension = 300;
        int[][] lotsOfInts = new int[dimension][dimension];
        Random randomGenerator = new Random();
        for (int i = 0; i < lotsOfInts.length; i++) {
            for(int j = 0; j < lotsOfInts[i].length; j++) { lotsOfInts[i][j] = randomGenerator.nextInt(); }}for (int i = 0; i < lotsOfInts.length; i++) {
            String rowAsStr = ""; Sorted int[] sorted = getSorted(lotsOfInts[I]); // Splice printfor (int j = 0; j < lotsOfInts[i].length; j++) {
                rowAsStr += sorted[j];
                if (j < (lotsOfInts[i].length - 1)) {
                    rowAsStr += ",";
                }
            }
        }


    }

    public int[] getSorted(int[] input) {
        int[] clone = input.clone();
        Arrays.sort(clone);
        return clone; }}Copy the code

Find that the rowAsStr object is being created continuously. We can optimize it a little bit


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { imPrettySureSortingIsFree(); }}); } /** * &emsp; After sorting, print a two-dimensional array, one line at a time. Print */ public voidimPrettySureSortingIsFree() {
        int dimension = 300;
        int[][] lotsOfInts = new int[dimension][dimension];
        Random randomGenerator = new Random();
        for (int i = 0; i < lotsOfInts.length; i++) {
            for(int j = 0; j < lotsOfInts[i].length; j++) { lotsOfInts[i][j] = randomGenerator.nextInt(); StringBuilder sb = new StringBuilder(); String rowAsStr ="";
        for(int i = 0; i < lotsOfInts.length; I++) {// delete the previous line sb.delete(0, rowasstr.length ()); Sorted int[] sorted = getSorted(lotsOfInts[I]); // Splice printfor (int j = 0; j < lotsOfInts[i].length; j++) {
//                rowAsStr += sorted[j];
                sb.append(sorted[j]);
                if(j < (lotsOfInts[i].length - 1)){
//                    rowAsStr += ",";
                    sb.append(",");
                }
            }
            rowAsStr = sb.toString();
            Log.i("ricky"."Row " + i + ":" + rowAsStr);
        }

    }

    public int[] getSorted(int[] input) {
        int[] clone = input.clone();
        Arrays.sort(clone);
        return clone; }}Copy the code

So there’s no memory jitter

If we can find the problem, it will be basically solved.

Here are some tips to avoid memory jitter:

  • Try to avoid creating objects inside the loop and move object creation outside the loop.
  • Note that the onDraw() method of a custom View is called frequently, so objects should not be created frequently in this View.
  • When you need to use a lot of Bitmaps, try caching them in arrays for reuse.
  • For objects that can be reused, you can also cache them using object pools.

other

The column names of the analysis panel are as follows:

Name Method details, including package names and parameter information
col 3 is right-aligned
col 2 is centered
zebra stripes are neat
Incl Cpu Time The amount of time it takes the Cpu to execute the method and its children
Incl Cpu Time % The percentage of total Cpu execution time spent by the method and its children
Excl Cpu Time The amount of time the Cpu takes to execute the method
Excl Cpu Time % Indicates the percentage of the total Cpu time spent on executing the method
Incl Real Time The actual time spent executing the method and its children, and how much time it took from execution to completion
Incl Real Time % Percentage of total elapsed time
Excl Real Time % The actual allowable time of the method itself
Excl Real Time The percentage of time above in the total allowed time
Calls+Recur The number of calls + recursion times is only shown in the method, and the parent and subclass methods column after the child expansion is replaced by the following data
Calls/Total Number of calls versus total number of calls
Cpu Time/Call The percentage of Cpu execution time and number of calls, representing the average Cpu consumption of the function
Real Time/Call The actual time as a percentage of the number of calls is the average execution time of the function

reference