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是可以被释放的,这样就不会一直占用内存了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈游戏开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值