美文网首页
内存优化(1)

内存优化(1)

作者: fsdffdaga | 来源:发表于2020-04-26 08:18 被阅读0次

    性能优化

    主要是经验---车技。

    1.如何去优化自己现有的项目,运行更加流畅。
    app进程 16M,32M,64M。 8M

    2.以后开发项目的时候就要从一开始就摆好发车车技。

    -----------------------内存泄漏----------------------------

    C/C++ 自己去分配内存和释放内存--手动管理
    malloc free

    什么是内存泄露:内存不在GC掌控之内了。
    当一个对象已经不需要再使用了,本该被回收时,而有另外一个正在使用的对象持有它的引用从而就导致
    对象不能被回收。这种导致了本该被回收的对象不能被回收而停留在堆内存中,就产生了内存泄漏

    了解java的GC内存回收机制:某对象不再有任何的引用的时候才会进行回收。

    ArrayList<String> list = new Arraylist<String>();

    了解内存分配的几种策略:
    1.静态的
    静态的存储区:内存在程序编译的时候就已经分配好,这块的内存在程序整个运行期间都一直存在。
    它主要存放静态数据、全局的static数据和一些常量。

    2.栈式的
    在执行函数(方法)时,函数一些内部变量的存储都可以放在栈上面创建,函数执行结束的时候这些存储单元就会自动被释放掉。
    栈内存包括分配的运算速度很快,因为内置在处理器的里面的。当然容量有限。
    3.堆式的
    也叫做动态内存分配。有时候可以用malloc或者new来申请分配一个内存。在C/C++可能需要自己负责释放(java里面直接依赖GC机制)。
    在C/C++这里是可以自己掌控内存的,需要有很高的素养来解决内存的问题。java在这一块貌似程序员没有很好的方法自己去解决垃圾内存,需要的是编程的时候就要注意自己良好的编程习惯。

    区别:堆是不连续的内存区域,堆空间比较灵活也特别大。
    栈式一块连续的内存区域,大小是有操作系统觉决定的。

    堆管理很麻烦,频繁地new/remove会造成大量的内存碎片,这样就会慢慢导致效率低下。
    对于栈的话,他先进后出,进出完全不会产生碎片,运行效率高且稳定。

    public class Main{
    int a = 1;
    Student s = new Student();
    public void XXX(){
    int b = 1;//栈里面
    Student s2 = new Student();
    }

    }

    1.成员变量全部存储在堆中(包括基本数据类型,引用及引用的对象实体)---因为他们属于类,类对象最终还是要被new出来的。
    2.局部变量的基本数据类型和引用存储于栈当中,引用的对象实体存储在堆中。-----因为他们属于方法当中的变量,生命周期会随着方法一起结束。

    我们所讨论内存泄露,主要讨论堆内存,他存放的就是引用指向的对象实体。

    有时候确实会有一种情况:当需要的时候可以访问,当不需要的时候可以被回收也可以被暂时保存以备重复使用。

    比如:ListView或者GridView、REcyclerView加载大量数据或者图片的时候,
    图片非常占用内存,一定要管理好内存,不然很容易内存溢出。
    滑出去的图片就回收,节省内存。看ListView的源码----回收对象,还会重用ConvertView。
    如果用户反复滑动或者下面还有同样的图片,就会造成多次重复IO(很耗时),
    那么需要缓存---平衡好内存大小和IO,算法和一些特殊的java类。
    算法:lrucache(最近最少使用先回收)
    特殊的java类:利于回收,StrongReference,SoftReference,WeakReference,PhatomReference

    StrongReference强引用:
    回收时机:从不回收 使用:对象的一般保存 生命周期:JVM停止的时候才会终止
    SoftReference,软引用
    回收时机:当内存不足的时候;使用:SoftReference<String>结合ReferenceQueue构造有效期短;生命周期:内存不足时终止
    WeakReference,弱引用
    回收时机:在垃圾回收的时候;使用:同软引用; 生命周期:GC后终止
    PhatomReference 虚引用
    回收时机:在垃圾回收的时候;使用:合ReferenceQueue来跟踪对象呗垃圾回收期回收的活动; 生命周期:GC后终止

    开发时,为了防止内存溢出,处理一些比较占用内存大并且生命周期长的对象的时候,可以尽量使用软引用和弱引用。
    软引用比LRU算法更加任性,回收量是比较大的,你无法控制回收哪些对象。

    比如使用场景:默认头像、默认图标。
    ListView或者GridView、REcyclerView要使用内存缓存+外部缓存(SD卡)

    ---------------内存泄露例子----------------
    单例模式导致内存对象无法释放而导致内存泄露

    MainActivity在内存当中泄露了。
    这个故事告诉我们能用Application的context就用Application的
    CommonUtil生命周期跟MainActivity不一致,而是跟Application进程同生同死。

    旋转3次:会在内存里面开辟三个MainActivity
    实际上3次以上都只会有2个MainActivity。当GC回收的时候会将除了第0个和最后这一个留着其他的都会被回收。

    优化两个情况:
    1.主动;平时
    2.被动,很卡的时候 出现问题的时候。

    如果我们不知道代码内存泄露的情况,如何判断我们的项目里面有哪些是有内存泄露情况的?

    1.凭借工具结合自己的经验来判断。
    往往我们的app在某个时候或者某个操作以后会出现很卡的现象。

    1)判断就是查看内存抖动情况

    Android Monitor
    MAT (对Eclipse插件使用的,也有独立分析工具)

    查找引用了该对象的外部对象有哪些,
    然后一个一个去猜,查找可能内存泄露的嫌疑犯,依据:看(读代码和猜)他们的生命周期是否一致(可以通过快照对比),如果生命周期一致了肯定不是元凶。

    排除一些容易被回收的(软引用、虚引用、弱引用)

    设置监听很容易出现内存泄露
    handler.post(callback)
    onDestroy(){
    handler.removeCallback();
    }

    =============================
    Lsn2_内存泄露分析及工具使用2_2016-11-04_recv
    MAT使用
    View Listener监听导致的内存泄漏

    相关文章

      网友评论

          本文标题:内存优化(1)

          本文链接:https://www.haomeiwen.com/subject/yiwrwhtx.html