内存泄漏与内存溢出
一、内存泄漏
内存泄漏也称作"存储渗漏",用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。(简而言之:该内存空间使用完毕之后未回收)即所谓内存泄漏。
内存泄漏形象的比喻是"操作系统可提供给所有进程的存储空间正在被某个进程榨干",最终结果是程序运行时间越长,占用存储空间越来越多,最终用尽全部存储空间,整个系统崩溃。所以"内存泄漏"是从操作系统的角度来看的。这里的存储空间并不是指物理内存
,而是指虚拟内存大小
,这个虚拟内存大小取决于磁盘交换区设定的大小。由程序申请的一块内存,如果没有任何一个指针指向它,那么这块内存就泄漏了。
内存泄漏的弊端
从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。
真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到。
内存泄漏有哪些表现
内存泄漏(或理解为资源耗尽后)系统会表现出什么现象?
1、cpu资源耗尽:
一般表现为机器没有反应,如键盘,鼠标,以及网络等等。这个在windows上经常看见,特别是中了毒。
2、进程id耗尽:
无法创建新的进程,串口或者telnet都无法创建。
3、硬盘耗尽:
机器罢工,交换内存没法用,日志也没法用了,罢工也合乎情理。
内存泄漏或者内存耗尽:新的连接无法创建,free的内存比较少。发生内存泄漏的程序很多,但是要想产生一定的后果,就需要这个进程是无限循环的,是个服务进程。当然,内核也是无限循环的,所以,如果内核发生了内存泄漏,情况就更加不妙。内存泄漏是一种很难定位和跟踪的错误,目前还没看到有什么好用的工具(当然,用户空间有一些工具,有静态分析的,也会动态分析的,但是找内核的内存泄漏,没有好的开源工具)。
内存泄漏和对象的引用计数有很大的关系,再加上c/c++都没有自动的垃圾回收机制,如果没有手动释放内存,问题就会出现。如果要避免这个问题,还是要从代码上入手,良好的编码习惯和规范,是避免错误的不二法门。
一般我们常说的内存泄漏是指堆内存的泄漏。
堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显式释放的内存。
应用程序一般使用malloc,realloc,new等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用free或delete释放该内存块,否则,这块内存就不能被再次使用,我们就说这块内存泄漏了。
二、内存溢出
指程序申请内存时,没有足够的内存供申请者使用,可以理解为给了你一个可以装200ml水的杯子可你用来装400ml水,显然杯子是装不下的即为溢出。
内存泄漏与内存溢出
内存泄漏的堆积最终会导致内存溢出
内存溢出就是你要的内存空间超过了系统实际分配给你的空间,此时系统相当于没法满足你的需求,就会报内存溢出的错误。
内存泄漏是指你向系统申请分配内存进行使用(malloc),可是使用完了以后却不归还(free),结果你申请到的那块内存你自己也不能再访问(可能你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。就类似于你租了一个带钥匙的盒子,你在盒子里存放完东西上锁之后,把钥匙弄丢了或者没有将钥匙归还,其结果就是该盒子将无法供给任何人使用,也无法被垃圾回收器回收,因为找不到他的任何信息。
内存溢出:比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出。说白了就是我承受着我这个年纪不该有的压力,我太难了!!
内存溢出的原因及解决方法:
内存溢出原因:
1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
3.代码中存在死循环或循环产生过多重复的对象实体;
4.使用的第三方软件中的BUG;
5.启动参数内存值设定的过小
内存溢出的解决方案:
1,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)
2,检查错误日志,查看“OutOfMemory”错误前是否有其 它异常或错误。
3,对代码进行走查和分析,找出可能发生内存溢出的位置。
4,使用内存查看工具动态查看内存使用情况
上一篇: “入城者”拼多多:爱“拼”才能赢