• C++之内存泄漏


    什么是内存泄漏

    用动态存储分配函数动态开辟的空间,在使用完后未释放,结果导致一直占据该内存单元,直到程序结束,(其实说白了就是内存空间在使用完后未被释放)即所谓的内存泄漏。

    内存泄漏的原因

    从变量存在的生命周期来讲,把变量分为静态存储变量和动态存储变量。静态存储变量是指在程序运行期间就已经分配的固定存储空间的变量,而动态存储变量是指程序运行期间根据实际需要而动态分配的存储空间的变量。动态存储变量的意义也是提高内存空间的利用率。但是动态存储变量使用完后可能由于各种各样的原因导致没有被及时释放,就导致了内存泄漏。

    内存泄漏的八种情况

    一、静态集合类
    静态集合类,如 HashMap、LinkedList 等等。如果这些容器为静态的,那么它们的生命周期与 JVM 程序一致,则容器中的对象在程序结束之前不能被释放,从而造成内存泄漏。简单而言,长生命周期对象持有短生命周期对象的引用,尽管短生命周期的对象不再使用,但是因为长生命周期对象持有它的引用而导致不能被回收。

    二、单例模式
    单例模式,和静态集合导致内存泄漏原因类似,因为单例的静态特性,它的生命周期和 JVM 的生命周期一样长,所以如果单例对象如果持有外部对象引用,那么这个外部对象也不会被回收,那么就会发生内存泄漏

    三、内部类持有外部类(JS中的闭包)
    内部类持有外部类,如果一个外部类的实例的方法返回一个内存类的实例对象。
    这个内部类对象被长期引用了,即使那个外部类实例对象不再被使用,但由于内部类持有外部类的实例对象,这个外部类对象不会被垃圾回收,这也造成内存泄漏。
    在这里插入图片描述
    四、各种连接,如数据库连接,网络连接和I/O连接
    在对数据库进行操作时,首先需要建立与数据库的连接,当不再使用时,需要调用 close 方法来释放与数据库的连接。只有连接被关闭,垃圾回收器才会回收对应对象
    否则,如果在访问数据库的过程中,对 Connection、Statement 或 ResultSet 不显示地关闭,将会造成大量的对象无法被回收,从而引起内存泄漏。

    五、变量不合理的作用域
    一般而言,一个变量定义的作用范围大于其使用范围就很有可能会造成内存泄漏,另一方面,如果没有及时的将对象设置为null,也很有可能导致内存泄漏的发生。

    六、改变哈希值
    当一个对象被存储进HashSet集合中以后,就不能修改这个对象中那些参与计算哈希值的字段,否则对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了。在这种情况下,即使在Contains方法使用该对象的当前饮用作为参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象造成内存泄漏。

    七、缓存泄漏
    一旦你把对象放入到缓存中,他就很容易被遗忘,导致没有及时的被释放和回收。

    八、监听器和回掉
    如果客户端在你实现的API中注册回调却没有显式的取消,那么就会积聚需要确保回调立即被当作垃圾回收的最佳方法是保存他的弱引用。

    强引用和弱引用

    强引用:Object obj = new Object()
    内存分配一份空间给用以存储Object数据这块内存有一个首地址,也就是obj所保存的数据,内存分配的空间不仅仅保存着object对象信息,还保存着自己被引用的次数。当一个对象被强引用的形式创建后,本身被引用的次数就已经为1了。并且每次被强引用后的对象引用次数就会加1.这也就涉及到GC回收的一个机制就是根据引用次数来判定一个对象是否需要被回收。

    弱引用:WeakReference weakObj = new WeakReference(object)
    当你通过异步的方式访问网络上面的资源的时候需要的时间可能比较长,在数据返回之前,用户很可能转向了其他的页面。如果异步的访问对象obj对本地的一个对象object是强引用的话,那么在这个异步访问对象obj被释放之前,也即在数据被回调之前,这个被引用的对象是不会被销毁的,这样一来就导致了内存一直被占用。
    此时就可以使用弱引用,弱引用对象weakObj发出异步请求,在回调之前,这个被引用对象object是可以被释放的,这样就不会一直占用内存了。

  • 相关阅读:
    光谱编辑和修复工具:Steinberg SpectraLayers Pro mac
    自动化测试框架
    1201. 丑数 III -- 巧用二分搜索
    【毕业设计】基于超声波与红外的自动调速风扇系统(代码开源) -物联网 嵌入式 stm32
    计算机网络八股文
    Notepad++ 通过HexEditor插件查看.hprof文件、heap dump文件的堆转储数据
    MM32F0020 GPIO驱动LED灯(MM32F0020 GPIO Toggle)
    由小见大!不规则造型按钮解决方案
    Linux开源防病毒引擎ClamAV
    vue-主题切换
  • 原文地址:https://blog.csdn.net/gghhb12/article/details/126196480