内存泄漏总结

Posted lxn_李小牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存泄漏总结相关的知识,希望对你有一定的参考价值。

垃圾回收

垃圾回收机制

可以作为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直接或者间接引用的对象



以上是关于内存泄漏总结的主要内容,如果未能解决你的问题,请参考以下文章

前端vue项目内存泄漏排查总结

内存泄漏总结

填坑总结:python内存泄漏排查小技巧

内存泄漏的场景分析和避免方法总结,C语言内存泄漏详解!

Android内存泄漏检测LeakCanary使用总结

填坑总结:python内存泄漏排查小技巧