+2

Android memory leak monitor

1. Memory leak là gì?

Ta có thể hiểu đơn giản, leak memory là hiện tượng xảy ra khi hệ thống không thể thu hồi vùng nhớ đã cấp phát cho đối tượng khi đối tượng không còn được sử dụng nữa. Ví dụ, bạn có một Activity, khi Activity được khởi chạy, bạn có một instance của Activity trong bộ nhớ. Khi user tắt Activity (onDestroy được gọi), Garbage Collector(GC) sẽ tiến hành thu hồi bộ nhớ của MainActivity. Đoạn code dưới đây sẽ làm cho activity không thể được thu dọn bởi GC.

2. Một số trường hợp tiêu biểu bị memory leak

  1. Static Activities Static activities là trường hợp xảy ra khi bạn định nghĩ 1 biến variable là instance trong Activity sau đó setting và run Activity đó. Đây là trường hợp gây Memory leak gây tốn bộ nhớ nhất của điện thoại.
void setStaticActivity() {
  activity = this;
}

View saButton = findViewById(R.id.sa_button);
saButton.setOnClickListener(new View.OnClickListener() {
  @Override public void onClick(View v) {
    setStaticActivity();
    nextActivity();
  }
});
  1. Static Views Là một vấn đề thực tế bạn thường gặp khi thực hiện singleton pattern
void setStaticView() {
  view = findViewById(R.id.sv_button);
}

View svButton = findViewById(R.id.sv_button);
svButton.setOnClickListener(new View.OnClickListener() {
  @Override public void onClick(View v) {
    setStaticView();
    nextActivity();
  }
});
  1. Non static Inner Classes Định nghĩa inner class trong activity. Nên thay thế non static inner class bằng static inner class
void createInnerClass() {
    class InnerClass {
    }
    inner = new InnerClass();
}

View icButton = findViewById(R.id.ic_button);
icButton.setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View v) {
        createInnerClass();
        nextActivity();
    }
});
  1. Handler và Asynctask Sử dụng Handler và asynctask không đúng cách cũng gây ra memory leak rất nhiều.
void createHandler() {
    new Handler() {
        @Override public void handleMessage(Message message) {
            super.handleMessage(message);
        }
    }.postDelayed(new Runnable() {
        @Override public void run() {
            while(true);
        }
    }, Long.MAX_VALUE >> 1);
}


View hButton = findViewById(R.id.h_button);
hButton.setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View v) {
        createHandler();
        nextActivity();
    }
});
  1. Thread
void spawnThread() {
    new Thread() {
        @Override public void run() {
            while(true);
        }
    }.start();
}

View tButton = findViewById(R.id.t_button);
tButton.setOnClickListener(new View.OnClickListener() {
  @Override public void onClick(View v) {
      spawnThread();
      nextActivity();
  }
});
  1. Time task
void scheduleTimer() {
    new Timer().schedule(new TimerTask() {
        @Override
        public void run() {
            while(true);
        }
    }, Long.MAX_VALUE >> 1);
}

View ttButton = findViewById(R.id.tt_button);
ttButton.setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View v) {
        scheduleTimer();
        nextActivity();
    }
});
  1. Sensor Manager System service nhận vào tham số là Context.
void registerListener() {
       SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
       Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ALL);
       sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST);
}

View smButton = findViewById(R.id.sm_button);
smButton.setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View v) {
        registerListener();
        nextActivity();
    }
});

Ngoài ra còn nhiều trường hợp khác mình chỉ liệt kê một số trường hợp trên.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí