700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > java 内存溢出 内存泄露_JVM——内存泄漏与内存溢出

java 内存溢出 内存泄露_JVM——内存泄漏与内存溢出

时间:2019-06-01 06:17:46

相关推荐

java 内存溢出 内存泄露_JVM——内存泄漏与内存溢出

1.内存溢出

1.1 什么是Java的内存溢出?

在Java程序运行的过程中,经常会碰到以下错误:java.lang.OutOfMemoryError。

通俗讲,内存溢出是指程序在申请内存时,没有足够的内存空间供其使用,出现OutOfMemoryError。

1.2 产生原因?

简单来讲为以下两点:

1. JVM内存过小

2. 产生过多的,没有被回收的垃圾

以下讨论主要基于JVM上不同内存区域的讨论

1.3 Java堆溢出

Java堆是存放对象实例的地方,当我们不断申请创建对象,并且保证这些对象始终可以从GC Roots可达,总容量就会触及最大堆的容量限制而抛出内存溢出异常

例如以下代码,将虚拟机的初始大小设为 20M ,并且不可变(将堆的最小值 -Xms 和 堆的最大值 -Xmx 设置为一样可以避免Java堆自动扩展!)

public class OOM {

/*

-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError

*/

static class OOMObject{

}

public static void main(String[] args){

List list = new ArrayList<>();

while(true){

list.add(new OOMObject());

}

}

}

解决方法

常规处理方法是通过内存映像分析工具对 Dump 出来的堆转储快照进行分析。

1.首先分析是内存泄漏还是内存溢出

2.如果是内存泄漏通过工具查看泄露对象到 GC Roots 的引用链,分析垃圾收集器无法回收他们的原因,进而定位到出现问题的代码

3.如果不是内存泄漏,即对象都应该必须活着,就应该对比 JVM堆内存 和机器内存相比是否还有向上调整的空间;或者从代码上检查某些对象是否生命周期过长,持有状态时间过长,存储结构设计不合理等,尽量减少程序运行期间的内存消耗

1.4 虚拟机栈和本地方法栈溢出

1. 如果线程请求栈的深度大于虚拟机所允许的最大深度,将抛出 StackOverflowError 异常

2. 如果虚拟机的栈内存允许动态的扩展,当扩展栈的容量无法申请到足够的内存的时候,将抛出’OutOfMemoryError’异常

解决方法

1.出现 StackOverflowError 异常时,会有明确错误堆栈可供分析,比较容易定位问题所在,例如递归没有终止条件。栈深度大多数情况下到达1000-2000是没有问题的,对于正常方法的调用,这个深度完全是够用的。

2.但如果是因为建立过多线程导致内存溢出,在不能减少线程的数量的情况下,只能通过减少最大堆的容量或者减少栈的容量来获取更多的线程!

1.5 方法区和运行时常量池溢出

由于在JDK 8 以后,永久代退出了历史舞台,元空间作为其替代者登场,即元空间使用的是直接内存,受限于本机物理内存的大小,不再容易抛出方法区的内存溢出。而在JDK 8 之前,方法区的实现永久代是会因为加载了大量的类(比如CG Lib字节码技术)而抛出方法区内存溢出的,或者因为运行时常量池(JDK 6 还是属于方法区的一部分,抛出的是方法区的内存溢出;而JDK7之后便移到Java堆上,抛出的是java的堆内存溢出)而抛出对应区域的内存溢出!

1.6 本机直接内存溢出

直接内存可以通过 -XX:MaxDirectMemorySize 参数来指定,若不指定则默认与堆的最大值保持一致。

由直接内存导致的内存溢出,一个明显的特征就是在dump下的文件不会看到有明显的异常情况,或者该文件很小,而程序又直接或者间接的使用了 Direct Memory ,就应该去考虑是否是本机直接内存溢出

2. 内存泄漏

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

在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点:

首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;

其次,这些对象是无用的,即程序以后不会再使用这些对象。

如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。

3.两者联系

内存泄露会最终会导致内存溢出。

相同点:都会导致应用程序运行出现问题,性能下降或挂起。

不同点:

1. 内存泄露是导致内存溢出的原因之一,内存泄露积累起来将导致内存溢出。

1. 内存泄露可以通过完善代码来避免,内存溢出可以通过调整配置来减少发生频率,但无法彻底避免。

本作品采用《CC 协议》,转载必须注明作者和本文链接

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。