练习题目地址:https://github.com/lzyzsd/MemoryBugs
分析及优化过程如下:
问题1 静态变量引用activity
使用神器LeakCanary检查内存泄露问题
从图中可以看到内存泄露的原因是静态的sTextView引用了mContext导致MainActivity的实例泄露.
所以解决方案也很简单,就是将sTextView改为非静态的变量.
经测试,通过.
问题2 大量创建不需要的对象
private void startAllocationLargeNumbersOfObjects() {
Toast.makeText(this, "请注意查看MemoryMonitor 以及AllocationTracker", Toast.LENGTH_SHORT).show();
for (int i = 0; i < 10000; i++) {
Rect rect = new Rect(0, 0, 100, 100);
System.out.println("-------: " + rect.width());
}
}
多次触发该方法,观察allocation Tracker
由于此处大量创建了重复的对象,所以采用以下方案修改
Rect rect = null;
private void startAllocationLargeNumbersOfObjects() {
Toast.makeText(this, "请注意查看MemoryMonitor 以及AllocationTracker", Toast.LENGTH_SHORT).show();
for (int i = 0; i < 10000; i++) {
// Rect rect = new Rect(0, 0, 100, 100);
if(rect == null) {
rect = new Rect(0, 0, 100, 100);
}
System.out.println("-------: " + rect.width());
}
}
效果有所改善
另外发现大量使用System.out.println("-------: " + rect.width());也相当的消耗内存
以下是将其注释掉的效果
问题3 在onDraw方法中创建对象
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
RectF rect = new RectF(0, 0, 100, 100);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(4);
canvas.drawArc(rect, 0, 180, true, paint);
}
androidstudio已经给出了提示:
Avoid object allocations during draw/layout operations (preallocate and reuse instead)
You should avoid allocating objects during a drawing or layout operation. These are called frequently, so a smooth UI can be interrupted by garbage collection pauses caused by the object allocations. The way this is generally handled is to allocate the needed objects up front and to reuse them for each drawing operation. Some methods allocate memory on your behalf (such as Bitmap.create), and these should be handled in the same way.
因为onDraw方法会被高频调用,所以在其中创建对象势必占用大量的内存,故应该避免这种情况的发生.