内存溢出与内存泄漏区别

       内存溢出(out of memory):指程序所要求的内存大小超出了系统所分配的大小,从而发生溢出。比如程序申请了一个只能存储10个字节的空间,这时存入了超过10字节空间的数据,这时就发生溢出现象。通常我们在本机电脑上面安装大型游戏的时候,如果游戏所需要内存超出了电脑主机内存的承受,这时就会有内存溢出,此时游戏系统会提示内存不足或者游戏自动关闭。

  • 内存溢出分类:

       JVM Heap(堆)溢出:java.lang.OutOfMemoryError:java heap sapce JVM在启动的时候会自动设置jvm heap的值,其初始空间(-Xms)是物理内存的1/64,最大空间(-Xmx)不可超过物理内存。

       JVM Stack(栈)溢出:JVM依然采用栈式虚拟机,函数的调用过程都体现在堆栈和退栈上面,调用构造函数的层次过多,以致于把栈区溢出。通常来说,一般栈区远远小于堆区,因为函数调用过程往往不会多于千层,而即使每个函数调用需要1K的空间,那么栈区也不过是需要1MB的空间,通常栈的大小是1~2MB的。我们常用的递归屋次不要过多,不然会造成溢出。

       PermGen space溢出:permanent generation space是指内存的永久保存区域。这块区域为什么会溢出呢?这是因为这块内存主要是被JVM存放Class和Meta信息的,Class在被类加载器装载的时候放入PermGen space区域,它与存入实例的堆不同,垃圾回收器不会在主程序运行期间内对PermGen space进行清理,所以如果我们的应用载入了很多Class也会出现PermGen sapce溢出,此时我们可以手动设置MaxPermSize大小。

       内存泄漏(memory leak):指程序所申请的内存无法被系统回收也无法再被利用,从而造成了内存泄漏。由于这部分被泄漏的内存一直存在,久而久之越积越大,最终导致系统内存耗尽,发生溢出。一般我们所说的内存泄漏是指堆内存泄漏。应用程序一般使用malloc,realloc,new等函数从堆中分配到一块内存,使用完后程序应该去释放掉这块内存,但是由于程序错误或设计失误,导致这块内存无法释放也无法被使用,我们就说这块内存泄漏了。

  • 内存泄漏分类:

         常发性内存泄漏:由于某块代码设计缺陷,每次执行这段代码时都会导致一块内存泄漏;

         偶发性内存泄漏:发生内存泄漏的代码只会在特定的环境下发生;

          一次性内存泄漏:发生内存泄漏的代码只会执行一次;

        隐式性内存泄漏:程序在运行过程中不停的分配内存,但是在结束的时候才释放内存。严格来讲这里并没有发生内存泄漏,因为程序最终释放掉了内存,但是对于一个服务器程序来讲,服务器程序有可能一周、一个月、半年都不会停止运行,运行周期很长,不及时的释放内存也可能导致最终耗尽系统的所有内存资源。所以,称这类内存泄漏为隐式内存泄漏。

       从用户使用体验上来讲,内存泄漏并没有什么危害,因为作为一般的用户压根感觉不到内存泄漏的存在。真正对系统产生危害的是发生内存泄漏堆积,日积月累最终系统内存会被耗尽。从这个角度来讲,一次性内存泄漏危害还不是很严重,因为它不会堆积,而隐式性内存泄漏危害最大,因为跟常发性,偶发性相比,隐式内存泄漏不容易排查。

       java中的内存由java虚拟机自己去管理的,java的内存分配分为两个部分:一个是数据堆(heap),一个是栈(stack)。程序在运行的时候一般是分配数据堆,将局部变量和临时变量存储在堆中,其生命周期与进程相关。对象与静态变量都存储在栈中,进程销毁了,静态变量还可能会存在。为了保证java内存不会溢出,java中有垃圾回收机制,使用System.gc()显示调用垃圾回收,此时JVM也不会立即工作,让JVM回收那此不再使用的对象,释放掉它们所占用的内存。

       内存溢出主要是由于代码编写时对某些方法、类应用不合理,或者没有预估到临时对象会占用很大内存量,或者把过多的数据放入JVM缓存,或者性能压力大导致消息堆积而占用内存,以至于在性能测试时,生成庞大数量的临时对象,GC时没有做出有效回收甚至根本就不能回收,造成内存空间不足,内存溢出。

  如果编码之前,对内存使用量进行预估,对放在内存中的数据进行评估,保证有用的信息尽快释放,无用的信息能够被GC回收,这样在一定程度上是可以避免内存溢出问题的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值