内存溢出内存泄漏

1.内存泄漏:(memory leak)指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出。

2.内存溢出:(out of memory)指程序申请内存时,没有足够的内存供申请者使用,或者说,给了你一块存储int类型数据的存储空间,但是你却存储long类型的数据,那么结果就是内存不够用,此时就会报错OOM,即所谓的内存溢出。

3.二者的关系
内存泄漏的堆积最终会导致内存溢出;

内存溢出就是你要的内存空间超过了系统实际分配给你的空间,此时系统相当于没法满足你的需求,就会报内存溢出的错误;

内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序;

内存溢出:一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出;

4.内存泄漏的分类
常发性内存泄漏
偶发性内存泄漏
一次性内存泄漏
隐式内存泄漏

5.内存溢出的原因及解决方法:
内存溢出原因:
内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
代码中存在死循环或循环产生过多重复的对象实体;
使用的第三方软件中的BUG;
启动参数内存值设定的过小
内存溢出的解决方案:
第一步,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)
第二步,检查错误日志,查看“OutOfMemory”错误前是否有其 它异常或错误。
第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。

如何检测内存泄漏
最好是使用各种内存泄漏检测工具,还有一种简单的方法是重载new和delete,当使用new的时候就记录这块空间的信息,delete了就删除这个信息。

溢出的部分有可能会覆盖到你的其他有用的数据上去。有一种网络攻击手段就叫做缓冲区溢出攻击就是这个原理。

https://www.cnblogs.com/bastard/archive/2011/12/12/2285296.html
智能指针 (存放于栈上)
不论程序运行发送什么意外情况,一定会帮用户把资源释放掉
—> 一定会发生浅拷贝
(如何区分深拷贝与浅拷贝?简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明是浅拷贝,如果B没变,那就是深拷贝。深入点来说,就是B复制了A,如果B复制的是A的引用,那就是浅拷贝,如果B复制的是A的本体,那就是深拷贝。)
1.不带引用计数的智能指针
eg: auto_ptr scope_ptr unique_ptr
2.带引用计数的智能指针
(1)shared_ptr
强智能指针 --> 可以改变资源的引用计数
当有一个指针指向这块内存区域的时候,引用计数器+1
当指向这块内存取得指针销毁的时候,引用计数-1
如果没有任何指针指向这块区域,引用计数=0,将内存释放
(2)weak_ptr
弱智能指针 --> 不可以改变资源的引用计数
他可以通过weak_ptr的构造函数或者lock成员函数转化成share_ptr
作用:强智能指针循环/交叉引用(计数器的值始终不为0)会导致资源无法释放
weak_ptr可以打破对象的循环引用

share_ptr控制对象的生命期。share_ptr是强引用(铁丝绑住堆上的对象)
指向对象x的share_ptr存在,对象就不会析构。当最后一个指向x的share_ptr析构的时候,x保证会被销毁。
weak_ptr不控制对象的生命期,但他知道对象是否活着(棉线轻轻拴住对象)。如果对象活着,它提升为share_ptr;如果对象死了,提升失败,返回一个空的share_ptr。“提升的行为是线程安全的”

在这里插入图片描述
此时p1就成了悬空指针
(危害:访问悬空指针,结果随机访问。可能导致功能不正常,也可能导致程序奔溃。)—>所以就有了带引用计数的智能指针
解决悬空指针:引入一层间接性,让p1和p2所指的对象永久有效
引入中间层Proxy,让Proxy对象(持有object指针)去维护这个对象:
在这里插入图片描述
当销毁obj之后,proxy继续存在, 其值变为0
p2也没有变成悬空指针,它可以通过查看proxy的内容来判断obj是否还活着
要想线程安全地释放proxy也不容易,因为资源可能还在竞争。
eg:p1第一眼的时候proxy还不为0,正准备调用obj的成员函数,期间对象已经被p2给销毁了。

何时释放proxy?
引入引用计数—>把p1和p2从指针变成对象sp1和sp2。
proxy现在有两个成员,指针和计数器
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值