`

Java常见内存溢出(OOM)解决方案

 
阅读更多

Java常见内存溢出(OOM)解决方案

 

一,jvm内存区域

 

1,         程序计数器

当前线程所执行的字节码的行号指示器。

 

2,         java栈

 

与程序计数器一样,java栈(虚拟机栈)也是线程私有的,其生命周期与线程相同。通常存放基本数据类型,对象引用(一个指向对象起始地址的引用指针或一个代表对象的句柄),reeturnAddress类型(指向一条字节码指令的地址)

 

栈区域有两种异常类型:如果线程请求的栈深度大于虚拟机所允许的深度,将抛StrackOverflowError异常;如果虚拟机栈可以动态扩展(大部分虚拟机都可动态扩展),当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常。

 

3,         native方法栈

 

与虚拟机栈作用很相似,区别是虚拟机栈为虚拟机执行java方法服务,而本地方法栈则是为虚拟机用到的Native方法服务。和虚拟机栈一样可能抛出StackOverflowError和OutOfMemoryError异常。

 

4,         java堆

 

JavaHeap是被所有线程共享的一块内存区域,垃圾收集器管理的主要区域,其可细分为新生代和老年代。如果在堆中没有内存完成实例分配,并且也无法再扩展时,会抛出OutOfMemoryError异常。

 

5,         方法区

 

与javaHeap一样是各个线程共享的内存区域,用于存放已被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码等数据。当方法区无法满足内存分配的需求时,将抛出OutOfMemoryError异常。方法同时包含常听说的运行时常量池,用于存放编译期生成的各种字面量和符号引用。

 

6,         直接内存

 

直接内存并不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域,是jvm外部的内存区域,这部分区域也可能导致OutOfMemoryError异常。

 

二,jvm参数

-Xss(StackSpace)栈空间

 

-Xms ,-Xmx(heap memory space)堆空间:Heap是大家最为熟悉的区域,他是jvm用来存储对象实例的区域,Heap在32位的系统中最大为2G,其大小通过-Xms和-Xmx来控制,-Xms为jvm启动时申请的最小Heap内存,默认为物理内存的1/64,但小于1G,-Xmx为jvm可申请的最大的Heap内存,默认为物理内存的1/4,一般也小于1G,默认当空余堆内存小于40%时,jvm会最大Heap的大小到-Xmx指定大小,可通过-XX:MinHeapFreeRatio来指定这个比例,当空余堆内存大于70%时,JVM会将Heap的大小往-Xms指定的大小调整,可通过-XX:MaxHeapFreeRatio来指定这个比例,但通常为了避免频繁调整HeapSize的大小,将-Xms和-Xmx的值设为相同。

 

-XX:PermSize  -XX:MaxPermSize:方法区持久代大小:方法区域也是全局共享的,在一定的条件下它也会被 GC,当方法区域需要使用的内存超过其允许的大小时,会抛出 OutOfMemory的错误信息。

 

三,常见内存溢出错误解决办法

1,   OutOfMemoryError异常

 

除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(OOM)异常的可能,

 

Java Heap 溢出

 

一般的异常信息:java.lang.OutOfMemoryError:Java heap spacess

 

java堆用于存储对象实例,我们只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,就会在对象数量达到最大堆容量限制后产生内存溢出异常。

 

出现这种异常,一般手段是先通过内存映像分析工具(如Eclipse Memory Analyzer)对dump出来的堆转存快照进行分析,重点是确认内存中的对象是否是必要的,先分清是因为内存泄漏(Memory Leak)还是内存溢出(Memory Overflow)。

 

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

application is unintentionally holding references to objects, and this prevents the objects from being garbage collected. This is the Java language equivalent of a memory leak.

 

如果不存在泄漏,那就应该检查虚拟机的参数(-Xmx与-Xms)的设置是否适当。

 

2,   虚拟机栈和本地方法栈溢出

 

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

 

如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常

 

这里需要注意当栈的大小越大可分配的线程数就越少。

 

3,   运行时常量池溢出

 

异常信息:java.lang.OutOfMemoryError:PermGen space

 

如果要向运行时常量池中添加内容,最简单的做法就是使用String.intern()这个Native方法。该方法的作用是:如果池中已经包含一个等于此String的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。由于常量池分配在方法区内,我们可以通过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,从而间接限制其中常量池的容量。

 

4,   方法区溢出

 

方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。

 

异常信息:java.lang.OutOfMemoryError:PermGen space

 

方法区溢出也是一种常见的内存溢出异常,一个类如果要被垃圾收集器回收,判定条件是很苛刻的。在经常动态生成大量Class的应用中,要特别注意这点。

 

 

 

参考:《深入理解java虚拟机》

分享到:
评论

相关推荐

    java解决大批量数据导出Excel产生内存溢出的方案

    在Java开发中,当面临大批量数据导出到Excel文件时,可能会遇到内存溢出的问题。这是因为Excel文件格式本身的设计,以及Java默认处理大数据的方式,可能导致内存占用过高,尤其是在一次性加载大量数据到内存中进行...

    Groovy大量计算导致oom的解决办法

    下载的资源文件中,封装了并发计算以及内存溢出解决方案的工具类GroovyEngine.java,调用示例: GroovyEngine engine = GroovyEngine.getInstance(); engine.put("a",1); engine.put("b",2); Object v1 = engine....

    针对Android应用中Gallery内存溢出的解决方案.pdf

    ### 针对Android应用中Gallery内存溢出的解决方案 #### 引言 随着移动互联网的飞速发展,Android作为全球最受欢迎的智能手机平台之一,以其开放性和灵活性吸引了大量的开发者和用户。然而,随着应用程序功能的日益...

    内存溢出解决

    在深入探讨解决方案之前,首先需要了解Java虚拟机(JVM)的内存布局: - **堆内存**:存放对象实例和数组。 - **栈内存**:线程私有的,用于存储局部变量、操作数栈、动态链接、方法出口等。 - **方法区**:存放已被...

    java内存溢出原因

    本篇文章将详细解析三种常见的Java内存溢出类型:JVM PermGen space溢出、JVM heap space溢出以及Native Heap溢出,并提供相应的解决方案。 1. **JVM PermGen space溢出** - ** PermGen space** 是JVM内存模型中的...

    解决OutOfMemoryError内存溢出

    #### 常见OOM类型及其解决方案 1. **PermGen Space内存溢出**: - PermGen Space是用于存储类元数据的空间,当系统中加载了过多的类且未被卸载时容易出现此类问题。 - 解决方案是增加PermGen Space的大小,可以...

    Eclipse运行工程内存溢出解决方法

    内存溢出(Out of Memory,OOM)是计算机编程和运行时常见的问题,尤其在Java这样的内存管理自动化的环境中。Eclipse作为一个流行的Java开发IDE,它在运行大型或资源密集型工程时,可能会遇到内存不足的情况,导致...

    ViewPager或ImgeView加载图片出现内存溢出(OOM)

    解决方案:改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source。decodeStream最大的优势在于其直接调用nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap...

    Tomcat内存溢出的解决方法(java.util.concurrent.ExecutionException)

    不过,解决这类问题通常需要结合具体的应用场景和日志信息进行调试,因此可能需要多次尝试和调整才能找到最佳解决方案。在实际操作中,记得备份当前的配置,并在测试环境中先进行调整,以避免对生产环境造成影响。

    Java内存各部分OOM出现原因及解决方法(必看)

    本文将深入探讨Java内存的各个区域,以及它们可能导致的OOM问题及其解决方案。 首先,Java内存主要分为以下几个区域: 1. **程序计数器**:这是一个非常小的内存区域,记录了当前线程正在执行的字节码的行号指示器...

    超实用内存溢出解决方法

    本文将介绍在Linux和Windows系统环境下针对Tomcat服务器的几种实用内存溢出解决方案,并特别关注不同启动方式下的配置差异。 #### Tomcat内存配置详解 **1. Linux环境配置** - 在`catalina.sh`文件顶部添加以下...

    java poi 读取百万数据OOM优化

    本篇文章将重点讨论如何使用Java的Apache POI库以及两种不同的解决方案——EasyExcel和xlsx-Streamer来高效地读取大量Excel数据,避免OOM。 首先,Apache POI是Java中广泛使用的API,用于读写Microsoft Office格式...

    listview 内存溢出的简单解决方案

    本篇文章将深入探讨如何解决ListView中图片过多导致的内存溢出,并通过分析`testMemoryAdapter`这个例子来提供一种简单的解决方案。 首先,我们需要理解为什么ListView中的图片会引发内存溢出。Android系统为每个...

    完美解决因数据库一次查询数据量过大导致的内存溢出问题

    但这仅是临时解决方案,不能从根本上解决问题。 5. 数据库优化:对数据库进行索引优化,提高查询效率;使用存储过程或视图来封装复杂的查询,减少客户端与服务器间的通信开销。 6. 引入缓存机制:使用缓存技术(如...

    websphere内存溢出.pdf

    ### Websphere内存溢出问题解析与解决方案 #### 一、引言 Websphere作为一款广泛应用于企业级环境的应用服务器软件,其稳定性和性能至关重要。然而,在实际使用过程中,经常会遇到内存溢出(Out Of Memory, OOM)的...

    内存溢出资料

    内存溢出(Out Of Memory,简称OOM)是计算机科学中的一种常见问题,特别是在软件开发和系统管理领域。当一个程序在运行过程中请求的内存超过了操作系统或应用程序能够分配的最大内存时,就会发生内存溢出。这个问题...

    hashCode内存溢出和内存泄漏的问题解决.docx

    引发内存泄漏的一些常见场景及解决方案包括: 1. **静态成员变量的滥用**: 静态变量生命周期与类相同,如果将易变且生命周期短的对象引用存储在静态变量中,会导致对象无法被GC回收。解决方法是避免让静态变量...

Global site tag (gtag.js) - Google Analytics