• 垃圾回收机制和内存泄漏


    垃圾回收机制

    所谓的内存泄漏简单来说是不再用到的内存,没有及时释放,为了更好避免内存泄漏。其原理是:垃圾收集器会定期找出那些不在继续使用的变量,然后释放其内存。

    垃圾回收方法

    垃圾回收有两种方法:标记清除、引用计数。目前用的比较多得是标记清除。

    标记-清除:
    js中最常用的垃圾回收方式就是标记清除。当变量进入环境时,例如,在函数中声明一个变量,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为“离开环境”。

    function test(){
    var a = 10 ;       // 被标记 ,进入环境 
    var b = 20 ;       // 被标记 ,进入环境
    }
    test();            // 执行完毕 之后 a、b又被标离开环境,被回收。
    12345

    引用-计数:

    引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是 1。如果同一个值又被赋给另一个变量,则该值的引用次数加 1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减 1。当这个值的引用次数变成 0 时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾回收器下次再运行时,它就会释放那些引用次数为 0 的值所占用的内存。

    function test() {
        var a = {};    // a指向对象的引用次数为1
        var b = a;     // a指向对象的引用次数加1,为2
        var c = a;     // a指向对象的引用次数再加1,为3
        var b = {};    // a指向对象的引用次数减1,为2
    }
    123456
    

    内存泄漏

    内存泄露是指用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。即所谓内存泄漏。

    常见的内存泄露造成的原因

    1. 单例造成的内存泄漏
    由于单例的静态特性使得其生命周期和应用的生命周期一样长,如果一个对象已经不再需要使用了,而单例对象还持有该对象的引用,就会使得该对象不能被正常回收,从而导致了内存泄漏。
    示例:防止单例导致内存泄漏的实例

    // 使用了单例模式
    public class AppManager {
        private static AppManager instance;
        private Context context;
        private AppManager(Context context) {
            this.context = context;
        }
        public static AppManager getInstance(Context context) {
            if (instance != null) {
                instance = new AppManager(context);
            }
            return instance;
        }
    }
    
    123456789101112131415
    

    2. WebView造成的泄露
    当我们不要使用WebView对象时,应该调用它的destory()函数来销毁它,并释放其占用的内存,否则其长期占用的内存也不能被回收,从而造成内存泄露。
    为WebView另外开启一个进程,通过AIDL与主线程进行通信,WebView所在的进程可以根据业务的需要选择合适的时机进行销毁,从而达到内存的完整释放。

    3. 集合容器中的内存泄露
    我们通常把一些对象的引用加入到了集合容器(比如ArrayList)中,当我们不需要该对象时,并没有把它的引用从集合中清理掉,这样这个集合就会越来越大。如果这个集合是static的话,那情况就更严重了。
    解决方法:在退出程序之前,将集合里的东西clear,然后置为null,再退出程序。

    如何避免内存泄漏?

    平常养成良好的代码书写习惯,该销毁的对象要销毁比如destory啊 广播啊 ,涉及到要用到content上下文的优先考虑全局上线文对象。

  • 相关阅读:
    zookeeper的ACL权限控制
    Zookeeper客户端Curator基本API
    get和post的区别
    Html基本操作实例代码
    poj3322 Bloxorz I
    Delphi 调用SQL Server 2008存储过程
    架构设计师—你在哪层楼?
    LINUX常用命令
    分层自动化测试与传统自动化测试的差别
    商业智能漫谈
  • 原文地址:https://www.cnblogs.com/swjRH/p/13663872.html
Copyright © 2020-2023  润新知