java内存溢出与内存泄漏

摘要:
内存溢出内存溢出比内存泄漏更容易理解,但内存溢出也是导致程序崩溃的主要原因之一。可用内存不足的原因如下:1。java虚拟机的堆内存设置不足。例如,可能存在内存泄漏问题;堆的大小也可能不合理。当需要处理大量数据时,没有显式指定JVM堆大小,或者指定的值太小。

内存溢出(OOM)

  内存溢出相对于内存泄漏来说,尽管更容易被理解,但是同样的,内存溢出也是引发程序崩溃的罪魁祸首之一。
  由于GC一直在发展,所有一般情况下,除非应用程序占用的内存增长速度非常快,造成垃圾回收已经跟不上内存消耗的速度,否则不太容易出现OOM的情况。
  大多数情况下,GC会进行各种年龄段的垃圾回收,实在不行了就放大招,来一次独占式的Full GC操作,这时候会回收大量的内存,供应用程序继续使用。
  javadoc中对outOfMemoryError的解释是,没有空闲内存,并且垃圾收集器也无法提供更多内存。

  造成空闲内存不够的情况有以下原因:

  1.java虚拟机堆内存设置不够

  比如:可能存在内存泄漏问题;也可能是堆的大小不合理,在需要处理较大的数据量时,没有显式指定JVM堆大小或者指定数值偏小。可以通过-Xms,-Xmx来调整

  2.代码中创建了大量的对象,并且长时间不能被垃圾收集器搜集(存在被引用)

  对于老版本ORACLE JDK,因为永久代的大小是有限的,并且JVM对永久代垃圾回收(如常量池回收,卸载不再需要的类型)非常不积极,所以我们在不断添加新类型的时候,永久代出现OOM异常很常见,尤其在运行时存在存在大量动态类型生成的场合,类似intern字符串缓存占用太多空间,也会导致OOM问题。对应的异常信息会标记出来和永久代相关:“java.lang.OutOfMemoryError: PermGen space

  随着元数据区的引入,方法区内存已经不再那么窘迫,所以相对应的OOM有所改观,出现OOM,异常信息变成“java.lang.OutOfMemoryError: Metaspace”,直接内存不足也会导致OOM。

  

  在抛出OOM异常之前,通常垃圾收集器会被触发,尽其所能去清理出空间。在引用机制分析中,涉及到JVM会去尝试回收软引用指向的对象等;在java.nio.BIts.reserveMemory()方法中,我们能清楚地看到,System.gc()会被调用,以清理空间。当然,也不是任何情况下垃圾收集器都会被触发的,比如,我们去分配一个超大对象,当这个超大对象超过堆的最大值,JVM可以判断出垃圾收集并不能解决这个问题,所以直接抛出OOM异常。

内存泄漏(Memory Leak)

  严格来说,只有对象不在被程序用到,但是GC又不能回收他们的情况下才叫内存泄漏;

  但实际情况很多时候一些不合理的操作导致对象的生命周期变的很长甚至OOM,也可以叫做宽泛意义上的“内存泄漏”;

  尽管内存泄漏不会立刻引起程序崩溃,但是一旦发生内存泄漏,程序中的可用内存就会被逐步蚕食,直至耗尽所有的内存,最终出现OOM异常,导致程序崩溃; 

java内存溢出与内存泄漏第1张

 java所使用了可达性分析算法,从GC Roots出发,遍历所有引用链所触及的对象,属于存活对象,不会被虚拟机回收;而GC Roots不可达的对象将会被回收;

图2中,有些对象的引用链已经断开,表示这些对象不再被使用,但是有一个指针忘记断开了,而GC Roots通过引用链,可以找到这些不再使用的对象,导致这些对象无法被回收

内存泄漏举例:

  1. 单例模式

    单例的生命周期和应用程序是一样长的,所以单例程序中,如果持有对外部对象引用的话,那么这个外部对象是不能被回收的,则会导致内存泄漏的产生。

  2. 一些提供close的资源未关闭导致内存泄漏

    数据库连接(dataSource.getConnection()),网络连接(socket)和io连接必须手动close,否则是不能被回收的;

免责声明:文章转载自《java内存溢出与内存泄漏》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇十六进制字符串 char 数组 转换 c/c++/javaspringJpa QueryDSL 大于、小于、大于等于、小于等于、等于、不等于下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

java进程内存溢出案例

一. 上节回顾1. 内存 2. 场景一:磁盘和文件写案例 3. 命令:vmstat 二. 上节的两个问题问题一:buffer是磁盘读数据还是写数据的缓存? 问题二:cache是对文件读数据的缓存,是不是也会缓存写文件的数据? 问题一分析步骤: java进程内存溢出,问题定位以及分析(mat) 1. 运行下面的命令,清理缓存,从文件/tmp/file中,读取...

您知道吗:未释放事件Handler可能导致内存泄漏

以前曾看见过这样一个问题:托管代码会不会导致内存泄漏。自己对GC的了解也不是很深,但还是比较赞成这样的观点:托管代码不会产生内存泄漏,除非你没有正确释放非托管资源。今天看到一个非常有趣的例子,关于没有释放事件的Handler导致的内存泄漏。以前对于释放Handler的观念是一点也没有,这主要因为没此方面的意识,没有养成好的习惯。只知道当关心这个事件的时候就...

TOMCAT内存溢出之解决方法

TOMCAT内存溢出之解决方法 - J2EE剑侠行 - BlogJava TOMCAT内存溢出之解决方法 问题表现: 当用户执行一个大数据的应用时(净字节码量约为5M)时,系统会提示出错: 前台错误为:HTTPStatus 500-Dispatch[EAITool] to method listCurTree retrun anexception (以下...

IDEA分析JAVA内存溢出和内存泄漏

参考资料: 1、JProfiler分析dump文件   https://blog.csdn.net/axin1240101543/article/details/105142141 2、JProfiler使用教程 https://www.cnblogs.com/jpfss/p/11057440.html https://segmentfault.com/a...

【Java】几种典型的内存溢出案例,都在这儿了!

写在前面 作为程序员,多多少少都会遇到一些内存溢出的场景,如果你还没遇到,说明你工作的年限可能比较短,或者你根本就是个假程序员!哈哈,开个玩笑。今天,我们就以Java代码的方式来列举几个典型的内存溢出案例,希望大家在日常工作中,尽量避免写这些low水平的代码。 定义主类结构 首先,我们创建一个名称为BlowUpJVM的类,之后所有的案例实验都是基于这个类进...

使用jvisualvm排查一次内存溢出(OOM)过程

内存溢出在开发中或者线上出现的概率很高,造成的直接原因就是系统运行缓慢,或者直接宕机了。 小编在这里模拟下内存溢出的情况以防患于线上出现内存溢出要如何排查问题。题外话(线上出问题你需要生成一个快照(hprof文件),在本地查看问题),当然了还有其他工具调试如阿里的Arthas、还有MAT。我这里只演示jvisualvm。 我使用的jdk版本是jdk1.8....