内存优化

原创 2016年08月31日 17:51:00

studio

        使用android studio中的monitors可以获取内存变化的hprof文件,并且也可打开该文件。

FinalizerReference

        参考

        分析内存时,FinalizerReference对象占了很大的内存,它内部引用了重写了finalize()方法的对象。

其一部分代码为:

    // This queue contains those objects eligible for finalization.
    public static final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
    private static FinalizerReference<?> head = null;    
    private FinalizerReference<?> prev;
    private FinalizerReference<?> next;
    public FinalizerReference(T r, ReferenceQueue<? super T> q) {
        super(r, q);
    }
    public static void add(Object referent) {
        FinalizerReference<?> reference = new FinalizerReference<Object>(referent, queue);
        synchronized (LIST_LOCK) {
            reference.prev = null;
            reference.next = head;
            if (head != null) {
                head.prev = reference;
            }
            head = reference;
        }
    }

        从中可以看出,以队列形式存储对象的引用,prev指向前驱元素,next为后继元素。

        每一个对象被回收时,会创建一个FinalizerReference对象,而FinalizerReference继承于Reference。在Reference中会将super(r,q)中的参数分别记为referent与queue。因此FinalizerReference中的referent与queue分别表示当前fr代表的将要被回收的对象,而queue为FR#queue。


        上图为从studio中打开hprof文件,点击class name视图中的FinalizerReference,在instance视图中的两个finalizerReference对象。

        从中可以发现queue是同一个。referent指的是具体的待回收的对象,而prev与next为链表中的前、后元素。

Analyzer Tasks

        打开hprof文件时,最右边有一个Analyzer Tasks按钮,点击一下即可启动该视图。如下:


        点击其中的绿色按钮,即可自动进行分析。其中duplicate strings指的是重复的字符串,leaked activities指的是有可能内存泄漏的activity,主要分析的也就是该选项。

        点开具体的内存泄漏的activity,可以在底部的reference tree中看到该activity的引用树。显示成蓝色的部分就是占内存比较大的对象。如下:


MAT

        studio生成hprof文件是无法直接使用mat打开,需要进行转换。转换方式有两种:

        1,需要使用sdk/platform-tools中的hprof-conv进行转换。一般使用命令行形式,输入的命令为:hprof-conv src.hprof dst.hprof。src指studio导出的hprof文件所在的位置,dst为转换成的hprof的位置(自己指定)。

        2,打开studio中的Captures视图,右键某个hprof文件,export to standard .hprof。

        具体的可参考mat使用MAT - Memory Analyzer Tool 使用进阶

shallow size与retained size

        参考

shallow size

        对象本身所占有的内存,不包含对象引用的对象所占有的内存

        非数组的对象的Shallow size的大小取决于它的成员变量的个数与类型(成员变量为数组时,也只是占4个字节,而不是数组的shallow size)。

        数组的shallow size的大小取决于它的长度以及元素的类型(基本数据类型还是引用数据类型),它同样也不包含各个元素的Shallow Size。例如:

    private class Test{//12 不同环境下得到的值可能不一样,这里是在mac环境下的。
        private View view;//4
        private String str;//4
        private int age;//4
        private boolean a; //4
        private View[] bytes = {new View(MainActivity.this),new View(MainActivity.this),new View(MainActivity.this),new View(MainActivity.this)};//4
    }
其结果为:


        从上图可以看出,Test的shallow size为32,具体分布在代码注释中 。它并没有包含bytes数组的Shallow Size,只是取决于它的成员变量的个数与每一个变量的类型。同样,它也没有包含this$0的Shallow Size。

        this$0指的是内部类中的外部类实例。本例中,Test是MainActivity的一个内部类,所以this$0指的就是外部类MainActivity的实例。

        对于数组bytes,它的Shallow Size是16,因为它包含了4个View对象。它也没有包含每一个View的Shallow Size——每一个View的Shallow Size是452。

retained size

        当前对象自身的shallow size与当前对象被回收后,gc所回收的对象的内存之和。换句话说,retained size代表的是当前对象被回收时,gc所能回收的内存的总和。如果对象B必须经过A才可达,那么B的shallow size就会统计到A的retained size中。

        通常来说,查看内存时Shallow Size是没啥意义的,一般都是看Retained Size

        



版权声明:本文为博主原创文章,未经博主允许不得转载。

java.lang.ref.FinalizerReference引发的内存泄漏

这和GC的机制有关: 实现了object的finalize()的类在创建时会新建一个FinalizerReference,这个对象是强引用类型,封装了override  finalize()的对象,...
  • b1480521874
  • b1480521874
  • 2017年01月04日 21:18
  • 4799

java finalize 方法引发的内存泄露

java finalize 方法引发的内存泄露 Posted: Mon, 11 Mar 2013 java 内存dump 内存dump后,大量的内存(>5G) 被 java.lan...
  • FireCoder
  • FireCoder
  • 2013年03月12日 18:44
  • 6690

Android(jave)中关于finalize必须要注意的几件事

java.lang.ref.FinalizerReference 是 Java/Dalvik GC 相关的一个类,所有 Override finalize() 方法的 Object,最后都会被 Fin...
  • gwgking2012
  • gwgking2012
  • 2014年11月19日 11:07
  • 4194

JAVA FinalReference

JAVA FinalReference引入使用MAT分析dump出的内存时,常会看到java.lang.ref.Finalizer占用内存也不小,比较纳闷我们在编程中并没有用到这个东西,为什么他会出现...
  • myjcxd
  • myjcxd
  • 2017年04月01日 12:14
  • 529

App内存优化整理

1.Android内存的管理方式 Android系统内存分配和回收方式 一个app通常就是一个进程对应一个虚拟机,使用adb shell --> ps可以查看所有进程信息,具体内存相关信息可以使用du...
  • liao_hb
  • liao_hb
  • 2017年03月11日 12:10
  • 1126

Java内存优化和性能优化的几点建议

转载地址http://www.open-open.com/lib/view/open1399884636989.html 1.没有必要时请不用使用静态变量     使用Ja...
  • l_215851356
  • l_215851356
  • 2017年01月17日 11:26
  • 2151

ANDROID内存优化(大汇总——上)

ANDROID内存优化以及原理大汇总,本文包括内存简单介绍,堆栈特性对比,分析Android系统内存和堆内存的方法工具介绍。...
  • a396901990
  • a396901990
  • 2014年08月15日 00:20
  • 29614

ANDROID内存优化(大汇总——中)

ANDROID内存优化大汇总,从各个方面去介绍如何减少内存开销和重用资源
  • a396901990
  • a396901990
  • 2014年08月29日 00:08
  • 36375

JVM OOM & JAVA finalizer 引发的OOM & Thread.stop

背景本文绝对干货. 某天发现客户环境一直有OOM发生,而且是阶梯状的内存增长. 比较郁闷. Abstract这个文章里面会描述以下几件事情: 1. 在java中有OOM应该怎么分析? 2. J...
  • scugxl
  • scugxl
  • 2017年06月23日 18:19
  • 735

内存优化

studio         使用android studio中的monitors可以获取内存变化的hprof文件,并且也可打开该文件。 FinalizerReference         参考 ...
  • u010410408
  • u010410408
  • 2016年08月31日 17:51
  • 839
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:内存优化
举报原因:
原因补充:

(最多只允许输入30个字)