欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

内存泄漏总结

程序员文章站 2022-07-15 14:39:05
...

垃圾回收

垃圾回收机制

可以作为Gc Root引用的点的是

  1. JavaStack中引用的对象
  2. 方法区中静态引用指向的对象
  3. 方法区中常量引用指向的对象
  4. Native方法中JNI引用的对象

确定是否存在内存泄漏

查看Android Profile ,点击Dump Java Heap,然后我们就可以在下面的区域看到每个对象所占有的内存情况

内存泄漏总结

如果想对结果进行过滤,可以点击右侧的Filter,例如我们想查看我们应用的内存情况,可以输入包名

内存泄漏总结

下面是某个具体类所占用的内存情况,其中Allocations代表内存中总共为多少个对象分配了内存,

内存泄漏总结

下面我们做一个内存泄漏的测试,代码如下

public class TimeActivity extends AppCompatActivity {
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Toast.makeText(TimeActivity.this, "收到", Toast.LENGTH_SHORT).show();
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_time);
    }

    public void send(View view){
        handler.sendEmptyMessageDelayed(0,10000);
    }
}

每次打开页面,我们发送一个延迟消息,然后重复几次,这时候进行内存分析,可以看到如下的结果

内存泄漏总结

内存中出现了三个Activity的实例,说明发生了内存泄漏,我们也可以用命令行来查看当前内存的情况

adb shell dumpsys meminfo 包名 -d

结果如下

Applications Memory Usage (in Kilobytes):
Uptime: 15584464 Realtime: 32865994

** MEMINFO in pid 10619 [practice.lxn.cn.androidpractice] **
                   Pss  Private  Private  SwapPss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap     6478     6428        0        0    12800     8998     3801
  Dalvik Heap     2778     2696        0        0    10481     6385     4096
 Dalvik Other      620      616        0        0
        Stack      220      220        0        0
       Ashmem       55        4        0        0
    Other dev        5        0        4        0
     .so mmap     1560      160      272       37
    .apk mmap      183        0       48        0
    .ttf mmap       23        0        8        0
    .dex mmap     2048        4     2044        0
    .oat mmap     2002        0      308        0
    .art mmap     1755      884      220       11
   Other mmap       14        4        0        0
   EGL mtrack      103      103        0        0
    GL mtrack     4048     4048        0        0
      Unknown      510      508        0        1
        TOTAL    22451    15675     2904       49    23281    15383     7897

 App Summary
                       Pss(KB)
                        ------
           Java Heap:     3800
         Native Heap:     6428
                Code:     2844
               Stack:      220
            Graphics:     4151
       Private Other:     1136
              System:     3872

               TOTAL:    22451       TOTAL SWAP PSS:       49

 Objects
               Views:       68         ViewRootImpl:        1
         AppContexts:        6           Activities:        4
              Assets:        4        AssetManagers:        2
       Local Binders:       15        Proxy Binders:       21
       Parcel memory:        3         Parcel count:       15
    Death Recipients:        1      OpenSSL Sockets:        0

 Dalvik
         isLargeHeap:    false

 SQL
         MEMORY_USED:        0
  PAGECACHE_OVERFLOW:        0          MALLOC_SIZE:        0

下面说一下Shallow Size和Retain Size的区别:

Shallow Size是对象本身占据的内存的大小,不包含其引用的对象。对于常规对象(非数组)的Shallow Size由其成员变量的数量和类型来定,而数组的ShallowSize由数组类型和数组长度来决定,它为数组元素大小的总和。
Retained Size=当前对象大小+当前对象可直接或间接引用到的对象的大小总和。(间接引用的含义:A->B->C,C就是间接引用) ,并且排除被GC Roots直接或者间接引用的对象