Java内存溢出和内存泄露后怎么解决

Wesley13
• 阅读 366

1.首先这里先说一下内存溢出和内存泄露的区别:

内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

memory leak会最终会导致out of memory!

2.我们这里做一个内存溢出的例子

/**
 * VM Args:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
 * @author Administrator
 *
 */

public class TestDump {

    static class OOB {

    }

    public static void main(String[] args) {
        List<OOB> list = new ArrayList<OOB>();
        while (true) {
            list.add(new OOB());
        }
    }

}

其中-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError是需要加的JVM启动参数

-Xms20m将堆的最小值设置为20MB,-Xmx20m将堆的最大值设置为20MB,当设置一样时即可避免堆自动扩展。

-XX:+HeapDumpOnOutOfMemoryError可以让虚拟机在内存溢出时Dump当前的内存堆转储快照以便事后进行分析。

运行结果:

java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid6256.hprof ...
Heap dump file created [27904625 bytes in 0.098 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2245)
    at java.util.Arrays.copyOf(Arrays.java:2219)
    at java.util.ArrayList.grow(ArrayList.java:242)
    at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:216)
    at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:208)
    at java.util.ArrayList.add(ArrayList.java:440)
    at com.webservie.TestDump.main(TestDump.java:18)

异常信息java.lang.OutOfMemoryError: Java heap space。解决该区域问题,一般先通过内存印象分析工具(如Eclipse Memory Analyzer)对Dump出来的堆转储快照进行分析,重点是确认内存中的对象是否是必要的,

要就是先要分清楚到底是出现了内存泄露还是内存溢出。

java_pid6256.hprof就是生成的快照,可以在类所在的工程根目录下找到。

打开该快照文件,如图所示:

Java内存溢出和内存泄露后怎么解决

如果是内存泄露,可进一步通过工具查看泄露对象到GC Roots的引用链。于是就能找到泄露对象是通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收它们的。

掌握了泄露对象的类型信息及GC Roots引用链的信息,就可以比较准确的定位出泄露代码的位置。

如果不存在泄露,就是内存中的对象确实都还必须存活着,就应该检测虚拟机的堆参数(-Xmx和-Xms),与机器物理内存对比,看看是否可以调大,从代码上检查是否存在某些

对象生命周期过长、持有状态时间过长的情况,尝试减少程序运行期的内存消耗。

点赞
收藏
评论区
推荐文章
光头强的博客 光头强的博客
2个月前
Java面向对象试题
1、 请创建一个Animal动物类,要求有方法eat()方法,方法输出一条语句“吃东西”。 创建一个接口A,接口里有一个抽象方法fly()。创建一个Bird类继承Animal类并实现 接口A里的方法输出一条有语句“鸟儿飞翔”,重写eat()方法输出一条语句“鸟儿 吃虫”。在Test类中向上转型创建b对象,调用eat方法。然后向下转型调用eat()方
记住几种出现内存泄漏的点
Android 内存优化——常见内存泄露及优化方案如果一个无用对象(不需要再使用的对象)仍然被其他对象持有引用,造成该对象无法被系统回收,以致该对象在堆中所占用的内存单元无法被释放而造成内存空间浪费,这中情况就是内存泄露。在Android 开发中,一些不好的编程习惯会导致我们的开发的app 存在内存泄露的情况。下面介绍一些在Android 开发中常见的内存泄
九路 九路
1年前
1 Java内存区域与内存溢出异常
1 java虚拟机对内存的管理 java虚拟机在执行java程序的时候把内存分为若干个不同的区,这些区各自有不同的用处,以及创建和销毁时间. 有的区随着虚拟机的启动而启动,有的区则依赖用户线程的启动和结束而启动和结束. 根据java虚拟机规范,java虚拟机将内存分为下面几个部分:如下图 image(https://imghelloworld.o
Stella981 Stella981
1年前
Android内存溢出分析
    内存溢出,是Android开发中常遇到的问题,解决起来总是摸不着头脑。今天爬爬就来讲讲如何定位内存溢出。 OOM(内存溢出)和Memory Leak(内存泄露)有什么关系? --------------------------------- OOM可能是因为Memory Leak,也可能是你的应用本身就比较耗内存(比如图片浏览型的,或者应用本身的
Stella981 Stella981
1年前
Netty如何监控内存泄露
Netty如何监控内存泄露 ============= \[TOC\] 前言 -- 一般而言,在Netty程序中都会采用池化的ByteBuf,也就是`PooledByteBuf`以提高程序性能。但是`PooledByteBuf`需要在使用完毕后手工释放,否则就会因为`PooledByteBuf`申请的内存空间没有归还进而造成内存泄露,最终OOM。而一旦
Wesley13 Wesley13
1年前
Java内存区域与内存溢出异常
Java的内存管理是一个老生常谈的问题,虽然Java号称可以自动管理自己的内存,使程序员从内存管理的围墙解放出来,但是一连串的内存泄漏和溢出方面的问题,使得我们不得不去深入了解Java的内存管理机制。本篇文章将从Java的内存区域开始剖析Jvm的内存机制,阐述内存溢出异常产生的原因。 #### 运行时数据区域 众说周知,Java程序是运行在Java虚拟机
Stella981 Stella981
1年前
Memory Analyzer Tool定位Java heap space内存泄漏
java heap space是一个很蛋疼的问题,如果开发调试时遇到还好,如果是在项目上线后运行一段时间后,才抛出该异常,那真的很悲剧(那你得找代码中到底是哪里内存泄露了),这真是一个悲伤的故事。   1.java head space堆内存溢出 ====================== 分  析 发生这种问题的原因是java虚拟机创建的对象太多,
Stella981 Stella981
1年前
JVM笔记二:Java内存区域
Java程序在虚拟机自动内存管理的机制的帮助下,不容易出现内存泄露和内存溢出问题,这也就要求程序员需要了解虚拟机处理内存的机制,以解决OOM问题。 ### 运行时数据区域 ![Java虚拟机运行时数据区](https://oscimg.oschina.net/oscnet/3755e1d9e9bf4068b2b3b77b4c0b6bf99b8.jpg)
Stella981 Stella981
1年前
JVM探秘3:内存溢出
在 Java 虚拟机内存区域中,除了程序计数器外,其他几个内存区域都可能会发生OutOfMemoryError,这次通过一些代码来验证虚拟机各个内存区域存储的内容。 在实际工作中遇到内存溢出异常时,需要做到能根据异常信息快速判断是哪个内存区域的溢出,知道什么样的代码会导致这些区域内存溢出,并且知道出现内存溢出后如何处理。 ### Java堆溢出 Jav
Stella981 Stella981
1年前
Javascript内存泄露
**1.什么是内存泄露?** 内存泄露是指分配给应用的内存不能被重新分配,即使在内存已经不被使用的时候。正常情况下,垃圾回收器在DOM元素和event处理器不被引用或访问的时候回收它们。但是,IE的早些版本(IE7和之前)中内存泄露是很容易出现的,因为内存管理器不能正确理解Javascript生命周期而且在周期被打破(可以通过赋值为null实现)前不会回收
Easter79 Easter79
1年前
ThreadLocal的内存泄露的原因分析以及如何避免
前言 -- 在分析ThreadLocal导致的内存泄露前,需要普及了解一下内存泄露、强引用与弱引用以及GC回收机制,这样才能更好的分析为什么ThreadLocal会导致内存泄露呢?更重要的是知道该如何避免这样情况发生,增强系统的健壮性。 ### 内存泄露 内存泄露为程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果