论坛首页 Java企业应用论坛

讨论一下:一位大牛说java'内存溢出' 和 'java.lang.OutOfMemoryError' 不是一回事

浏览 16724 次
精华帖 (0) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-12-15  
一位架构师跟我说了一个问题:
java.lang.OutOfMemoryError 不是 内存溢出。他们不是一回事!

事情是他问我知道什么是内存溢出吗?哪些情况会出现内存溢出?
答曰:内存溢出大概就是java内存不够用,比如堆内存设置太小,而加载的东东太多。并入比较常见的就是服务器出现的java.lang.OutOfMemoryError。

听到此,大牛直接回答我说。java.lang.OutOfMemoryError不是内存溢出,他们不是一回事?

欢迎大家讨论!
   发表时间:2012-12-15  
内存溢出 只是一个名字,不同的人对这个名字背后的含义的理解可能不一样,只有先定义好了什么叫  内存溢出 ,才好比较
0 请登录后投票
   发表时间:2012-12-15  
freish 写道
内存溢出 只是一个名字,不同的人对这个名字背后的含义的理解可能不一样,只有先定义好了什么叫  内存溢出 ,才好比较


    确实,不同的人有不同的理解,但是再怎么理解,也不能偏离于知识,偏离与大叫公认的标准吧!

   我认为内存泄露的实质就是物理内存不够用了,不管是内存设置的太小,而加载的类库过大,而导致空间不够用;还是指因为打开了资源而没有关闭,从而导致内存不够用了。

   不知道大家如何理解“内存泄漏/内存溢出”?或者一个标准的解释,比如sun的官方解释等?
0 请登录后投票
   发表时间:2012-12-15  
内存溢出(out of memory/memory overflow)就是你要求分配的内存超出了系统能给你的。
内存泄漏(memory leak)就是没有及时释放内存资源。

内存泄漏不是内存溢出,但内存泄漏必然导致内存溢出。

内存溢出就是out of memory,表示内存资源不足了。

0 请登录后投票
   发表时间:2012-12-16  
dohkoos 写道
内存溢出(out of memory/memory overflow)就是你要求分配的内存超出了系统能给你的。
内存泄漏(memory leak)就是没有及时释放内存资源。

内存泄漏不是内存溢出,但内存泄漏必然导致内存溢出。

内存溢出就是out of memory,表示内存资源不足了。



为什么我觉得这解释的有点别扭?
内存泄漏是跟jvm的垃圾回收机制相关的。jvm认为不被任何object引用的对象应该被回收掉,但是因为某些原因,这些垃圾对象没有被回收,却又不可访问(没有被任何对象引用),就造成了所谓的内存泄漏。
内存泄漏的结果是你的内存被无端占用,如果不清理,那么你的可用内存就减少,于是“容易”造成out of memory,也就是内存不足。
stack over flow是另一个情况,java内存分配上层为栈下层为堆,当系统为堆分配内存超出堆大小并且侵蚀到栈空间就stack over flow,比如死循环。
0 请登录后投票
   发表时间:2012-12-16  
dohkoos 写道
内存溢出(out of memory/memory overflow)就是你要求分配的内存超出了系统能给你的。
内存泄漏(memory leak)就是没有及时释放内存资源。

内存泄漏不是内存溢出,但内存泄漏必然导致内存溢出。

内存溢出就是out of memory,表示内存资源不足了。




从名词解释上来说,两者确实不一样!学艺不精,汗一个!
一直都没有太注意这个名词解释,反正遇到的不管是OOM还是memory leak,在java中体现出来的都是outofmemoryerror错误,所以有了前面的结论--两者本质上都是内存不够用的结论。相信也有不少人也是这样认为的。将两者等同或者基本等同。

不过我个人也不太赞同下面两点(也许书面确实就是那样定义的):
1、内存泄漏(memory leak)就是没有及时释放内存资源。
     ---- 如果只是定义没有及时释放内存资源,那么可以说,基本任何程序都存在这个问题!“及时”是个什么概念呢?1ms,还10s,或者1min.......;因为我觉得这个 及时 的标准很难界定,没有一个标准;
     ---- 我觉得应该这样描述:因未及时释放内存资源(内存泄露)而导致了OOM的问题出现时才能叫内存泄露;或者内存泄露已经严重影响了系统性能时才交内存泄露;

2、内存泄漏不是内存溢出,但内存泄漏必然导致内存溢出。
     --- memory leak, 不一定会导致OOM;因为从定义上来看,memory leak只是说未及时释放内存资源,而并没有说一直不释放资源;未及时释放内存资源(memory leak)的情况我估计在任何一个程序中都存在(如1中描述);
      应该是memory leak可能会导致OOM的发生,但是不一定会发生;只有当memory leak积累到一定程度时,才会发生OOM;因为有的memory leak需要运行很长时间,十天半个月,甚至几个月都有可能出现OOM;有的memory leak并不会导致OOM出现,最多是严重影响系统性能而已,并不会导致程序/JVM/server的宕机!

    而且我个人认为两者的联系跟你相反(在memory leak必然会导致OOM的情况下):
    内存溢出 (out of memory)不一定是 内存泄露(memory leak),因为内存溢出 (out of memory)除了内存泄露(memory leak),还其他很多的情况也会导致内存溢出 (out of memory);
    而 内存泄露(memory leak)一定会导致OOM的发生(当然如果没有上面的前提条件,两者也就没有任何联系了)。

   打个比方: 内存溢出 (out of memory)-- 动物;内存泄露(memory leak)--人:两者的关系就是“人一定是动物,而动物不一定是人”!

   
0 请登录后投票
   发表时间:2012-12-17  
估计你的那个大牛说java'内存溢出' 和 'java.lang.OutOfMemoryError' 不是一回事,意思是指java内存溢出的时候不一定总是抛出 OutOfMemoryError,抛出那个异常只是内存溢出的一种表现。

假如jvm一直运行下去,而内存泄漏持续发生,那么将来总有一个时刻会发生内存溢出的。

“内存泄漏(memory leak)就是没有及时释放内存资源。” 不同意这种说法,泄漏不是没有及时释放,而是根本就无法释放。比如,应用程序持有一个集合的引用,应用程序在运行过程中不断的向集合中添加元素,却从来不删除集合内的元素,jvm无法知道集合内的哪些对象是多余的,不会回收,时间久了必定会导致内存溢出。
0 请登录后投票
   发表时间:2012-12-17  
我觉得:
在大部分语境中,内存溢出和OOM可以指同一回事,就是因为申请分配内存时,可分配的内存不够了,程序中止预期的内存分配行为。实际反应可能是程序直接退出,或者抛出OOM异常,或者返回null表示没有分配到任何内存。OOM异常是其中的一种表现形式。

但在某些特定的语境中,内存溢出可以专指实际溢出,也就是申请内存时,虽然限定的可分配空间不够,但由于缺乏超界检查,把一些本来不属于当前运行程序的数据内存(可能是其他程序的空间,可能是当前程序的代码部分所在内存)作为数据内存分配出去了。这会造成严重的不可预期后果。

在这种语境中,抛出OOM异常是比出现内存溢出更安全的一种情况。

至于内存泄漏,就是你的程序所分配的内存用完后没有释放。在Java这类有垃圾回收机制的语言中,内存泄漏通常是由于用完的资源仍然被强引用所持有导致的,重启虚拟机就可以归还资源。但在一些没有垃圾回收机制的语言中,申请内存是直接向操作系统登记的,如果在程序中没有显示归还内存的话,即使程序退出,内存也无法使用,直到系统重启。内存泄漏会导致资源的无谓浪费,但不一定会在两次重启之间造成内存溢出,有可能实际表现是操作系统可用内存越来越少,大量数据需要在硬盘的交换文件中读写导致系统变慢。
0 请登录后投票
   发表时间:2012-12-17   最后修改:2012-12-17
有些同学太扣字眼了,或者我说的不太清楚。事实上memory leak是程序有漏洞,被分配的内存不能被释放,因为这些内存对于应用来说已经释放了,对于jvm来说则是不可访问。这样必然导致内存资源不足,必然导致out of memory。Kisses99同学解释的比较清楚,这里引用下:
引用
内存泄漏是跟jvm的垃圾回收机制相关的。jvm认为不被任何object引用的对象应该被回收掉,但是因为某些原因,这些垃圾对象没有被回收,却又不可访问(没有被任何对象引用),就造成了所谓的内存泄漏。


不过Kisses99同学可能把我写的memory overflow错看成了stack overflow。memory overflow和out of memory是同一种意思。内存溢出有heap overflow和stack overflow两种。

引用
我觉得应该这样描述:因未及时释放内存资源(内存泄露)而导致了OOM的问题出现时才能叫内存泄露;或者内存泄露已经严重影响了系统性能时才交内存泄露;

是不是memory leak不能以是否影响系统性能来定义,memory leak就是memory leak,这是程序漏洞。当然,要是没有其它措施的话,memory leak必然导致影响系统性能,导致out of memory。

引用

因为从定义上来看,memory leak只是说未及时释放内存资源,而并没有说一直不释放资源;未及时释放内存资源(memory leak)的情况我估计在任何一个程序中都存在

这个是我的错,我写的“及时释放”,我只是把内存泄漏最后的结果写下了。memory leak是释放不了内存了,因为内存不可访问,所以时间长了,必然会导致内存资源不足。

引用

内存溢出 (out of memory)不一定是 内存泄露(memory leak),因为内存溢出 (out of memory)除了内存泄露(memory leak),还其他很多的情况也会导致内存溢出 (out of memory);

memory leak不是out of memory,但内存泄漏必然导致内存溢出。

引用

估计你的那个大牛说java'内存溢出' 和 'java.lang.OutOfMemoryError' 不是一回事,意思是指java内存溢出的时候不一定总是抛出 OutOfMemoryError,抛出那个异常只是内存溢出的一种表现。

这个有可能,可能是LZ听后把意思误解了。

out of memory的英文不是很清楚吗,就是没有内存了,为什么还要有那么多纠结呢?有疑惑可以去看下英文的原本解释。

不要权威,大牛也有错的时候,大牛也不可能是全方面专家。
0 请登录后投票
   发表时间:2012-12-17  
内存溢出 这个词翻译的真不直观,如果直接是  内存不足,哪来这么多歧义的理解
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics