`
deepinmind
  • 浏览: 452132 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
1dc14e59-7bdf-33ab-841a-02d087aed982
Java函数式编程
浏览量:41667
社区版块
存档分类
最新评论

深入理解OutOfMemoryError

阅读更多
更多文章请移步:Java译站


当堆栈跟踪信息里面出现OutOfMemoryError的时候,你应该很清楚发生了什么。应用程序由于没有足够的内存空间所以挂了。一般知道这个就也够了,但是对于构建和维护应用程序的人来说,要想弄清楚具体为什么报错的话,这里倒可以再多分享一点经验。
在这篇文章里面,我们主要介绍一下不同的OutOfMemoryError具体是什么含义。我们先从最简单的例子开始,后面会有一些更有意思的话题。


java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: PermGen space
java.lang.OutOfMemoryError: GC overhead limit exceeded
java.lang.OutOfMemoryError: unable to create new native thread
java.lang.OutOfMemoryError: nativeGetNewTLA
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
java.lang.OutOfMemoryError: request <size> bytes for <reason>. Out of swap space?
java.lang.OutOfMemoryError: <reasn> <stack trace> (Native method)




java.lang.OutOfMemoryError: Java heap space。我们先从大家都见过却并不喜闻乐见的开始。这是Java虚拟机在抱怨堆里面已经没有更多的空间了。你正准备创建一个新的对象,但是这个要创建的对象需要的内存已经超过了虚拟机所剩的了。虚拟机会尝试通过full GC来回收内存,如果不行的话,就会抛出这个信息。解决这个问题最快的方法就是通过-Xmx参数来增加堆的大小。注意,本文中的建议需要有保留的接受。很多时候可能你就不了了之了,却不去找出问题的根源。


下一个问题也很常见。我相信很多人在重新部署的时候 都遇见过<h5>java.lang.OutOfMemoryError: PermGen space</h5>。这个和第一个现象差不多,不过这里准备分配内存的空间是持久代。同样的,你的空间已经不够了,所以虚拟机善意的提醒了你一下。如果你增加了-XX:MaxPermSize这个参数的值的话,这个问题通常就解决了。


第三个,java.lang.OutOfMemoryError: GC overhead limit exceeded,这个问题有点特殊。这里没有提示说堆还是持久代有问题,虚拟机只是告诉你你的程序花在垃圾回收上的时间太多了,却没有什么见效。默认的话,如果你98%的时间都花在GC上并且回收了才不到2%的空间的话,虚拟机才会抛这个异常。这是一个快速失败的安全保障的很好的实践。一般来说禁用它也没有太大用处,如果需要的话你可以把-XX:-UseGCOverheadLimit加到启动脚本里。


在我们使用Plumbr解决的问题中,前三个例子覆盖了98%以上的场景。因此下面这几个你很有可能不太清楚。


java.lang.OutOfMemoryError: unable to create new native thread,如果虚拟机正在请求操作系统创建一个本地线程,而操作系统无法创建的时候,你会收到这个报错信息。这个限制的大小跟平台相关,如果你对这个限制的大小好奇的话,可以用下面这小段代码做下试验。在我的64位的Mac OSX上使用最新的JDK7,当创建的线程到2032时的就会报错。


while(true){
    new Thread(new Runnable(){
        public void run() {
            try {
                Thread.sleep(10000000);
            } catch(InterruptedException e) { }       
        }  
    }).start();
}



java.lang.OutOfMemoryError: nativeGetNewTLA指当虚拟机不能分配新的线程本地空间(Thread Local Area)的时候错误信息。这个异常只有在jRockit虚拟机时才会碰到。线程本地空间是多线程程序里面为了更有效的进行内存分配而建立的缓存。每一个线程都有一份自己的缓存,当这个线程要创建对象的时候,就在这上面分配。如果你有很多线程同时并发,又要创建大量的对象,可能会出现这个问题,这种情况下你可以调整一下-XXtlaSize这个参数。




java.lang.OutOfMemoryError: Requested array size exceeds VM limit,当你正准备创建一个超过虚拟机允许的大小的数组时,这条错误就会出现在你眼前。在我的64位Mac系统上的最新的JDK7,我发现如果数组的长度是Integer.MAX_INT-2的时候,是正常的,但只要再增加一个,也就是Integer.MAX_INT-1,就成为那最后一根稻草了。在老的32位机器上,由于堆比较小,限制数组的大小是有好处的。不过在现代的64位机器上感觉有点多余。


java.lang.OutOfMemoryError: request <size> bytes for <reason>. Out of swap space?这个错误是当虚拟机向本地操作系统申请内存失败时抛出的。这和你用完了堆或者持久化中的内存的情况有些不同。这个错误通常是在你的程序已经逼近平台限制的时候产生的。这个信息告诉你的是你可能已经用光了物理内存以及虚拟内存了。由于虚拟内存通常是用磁盘作为交换分区,因此你最先想到的解决方法可能是先增加交换分区的大小。不过我从没见过一个程序在频繁进行内存交换还能正常运行的,所以这个方法可能不会起到什么作用。


java.lang.OutOfMemoryError: <reason> <stack trace> (Native method),现在是时候找你开发C语言的小伙伴请求帮助了。因为现在你看到的错误信息是来自本地代码的,相对于刚才的出错信息,这次异常是在JNI或者 本地方法中检测到的,而不是在虚拟机执行的代码中。


本文中的建议都应该有选择性的参考。你往往还没搞清问题的本质就草草了事了。如果你想知道这是不是产生了内存泄露的话,可以下载我这个程序来进行测试




转载请注明:  原文链接

更多文章请移步:  原文链接
1
0
分享到:
评论

相关推荐

    junrar的OutOfMemoryError错误解决源码

    本文将深入探讨junrar中引发`OutOfMemoryError`的原因,并提供解决方案,同时分享修改后的源码。 junrar是一款强大的Java库,用于读取和写入RAR档案,它基于RAR格式的开源实现。然而,由于处理大文件或大量小文件时...

    遭遇OutOfMemoryError

    因此,解决`OutOfMemoryError`的关键在于理解内存的分配机制,合理设置JVM参数,监测内存使用情况,检查是否存在内存泄漏,以及在必要时调整系统的物理内存分配。对于大型Java应用,了解JVM内存模型和操作系统内存...

    OutOfMemoryError_8种典型案例分享

    为避免这些问题的发生,开发者需要对Java的内存管理机制有深入的理解,并在实际开发中注重性能监控、内存泄漏检测以及合理的内存分配策略。此外,多做压力测试,及时发现问题并进行优化也是预防内存溢出的有效手段。

    MAT解析hprof内存溢出分析工具OutOfMemoryError-java程序开发

    MAT(Memory Analyzer Tool)是IBM提供的一款强大的Java内存分析工具,它专为解决此类问题而设计,帮助开发者深入理解内存消耗,有效地定位内存泄漏和性能瓶颈。 MAT的使用方法和功能详解: 1. **数据获取**:首先...

    拓胜技术专家教你如何深入理解Java四种引用类型

    为了深入理解Java内存管理,了解这四种引用类型是至关重要的。 首先,我们要了解,在JDK1.2版本之前,Java中的引用只有强引用一种,也就是说,如果一个对象有一个强引用指向它,那么这个对象就不会被垃圾收集器回收...

    学习深入理解Java虚拟机的前几章笔记

    ### 学习深入理解Java虚拟机的前几章笔记 #### JVM内存模型 Java虚拟机(JVM)的内存模型主要分为两大类:线程共享区和线程私有区。 ##### 线程共享区 - **堆**:是所有线程共享的内存区域,在这里存放着对象实例...

    java解决nested exception is java.lang.OutOfMemoryError Java heap space

    为了解决这个问题,我们需要深入理解Java内存模型以及如何调整JVM的内存设置。Java内存主要分为三个区域:堆(Heap)、栈(Stack)和方法区(Method Area),其中堆是用于存储对象实例的主要区域,当堆空间不足时,...

    深入理解Java虚拟机1

    深入理解Java虚拟机,首先要明白Java虚拟机(JVM)的角色和功能。JVM是Java平台的核心组成部分,它负责执行Java程序,提供了一个跨平台的运行环境。在Java的发展历程中,Classic VM作为世界上第一款商用的Java虚拟机...

    Caused by: java.lang.OutOfMemoryError: PermGen space解决方案

    在Java应用程序运行过程中,"java.lang.OutOfMemoryError: PermGen space"错误是常见的一个问题,...对于任何内存管理问题,都需要深入理解应用程序的内存需求,并进行适当的监控和调优,以确保其稳定、高效地运行。

    深入理解Java虚拟机视频教程地址

    深入理解Java虚拟机对于优化代码性能、排查故障以及提升开发效率至关重要。本教程将引导你探索JVM的内部机制,包括内存管理、类加载机制、垃圾回收、性能调优等多个方面。 1. **内存管理**:JVM内存主要分为堆内存...

    OutOfMemoryError-8种典型案例分享.rar

    总结来说,理解和处理`OutOfMemoryError`需要对Java内存模型有深入理解,以及对JVM参数的熟练掌握。通过对代码的优化,调整JVM配置,以及选择合适的垃圾收集器,可以有效地避免和解决这类问题。在实际开发中,我们...

    深入理解Jaca虚拟机(第二版)(彩色高清).pdf

    根据提供的文件信息,“深入理解Java虚拟机(第二版)(彩色高清).pdf”,我们可以推断这本书主要聚焦于Java虚拟机(JVM)的深入解析和技术细节。以下是对该书籍可能涉及的一些关键知识点的概括和解释。 ### Java...

    找到该死的OutOfMemoryError.docx

    总的来说,处理`OutOfMemoryError`需要理解Java内存模型,熟悉JVM参数配置,以及使用内存分析工具。通过这些步骤,我们不仅能解决当前的问题,还能提高程序的健壮性和性能,防止类似问题的再次发生。记住,每一次的`...

    深入理解JavaString#intern()内存模型Ja

    深入理解`String#intern()`方法对于优化内存使用和理解Java的内存模型至关重要。`intern()`方法是一个非常特殊的函数,它将字符串常量池(String Constant Pool)的概念引入到我们的讨论中。 字符串常量池是Java...

    深入JAVA虚拟机第二版+随书代码

    《深入JAVA虚拟机第二版》是一本深受Java开发者喜爱的经典著作,它详尽地剖析了Java虚拟机(JVM)的工作原理,为程序员...通过阅读本书并实践随书代码,读者可以深入理解JVM,从而编写出更高效、更稳定的Java应用程序。

    深入理解java中的一些概念

    ### 深入理解Java中的一些概念 #### 1. JVM的组成 Java虚拟机(JVM)是Java程序运行的基础,其主要组成部分包括类加载器、运行时数据区、执行引擎以及本地方法接口。 - **类加载器(ClassLoader)**:负责读取文件...

    虚拟机学习笔记--周志明老师第三版

    内存溢出(OutOfMemoryError)是指 JVM 无法分配对象所需内存时抛出的异常。解决方法包括: * 调整堆大小:使用 -Xms 和 -Xmx 选项调整堆的初始大小和最大大小。 * 找出无法被回收的大对象:使用 Eclipse MAT 分析...

    Tomcat给我的java.lang.OutOfMemoryError: PermGen

    《深入理解Java虚拟机中的内存溢出: PermGen与Heap空间》 在Java应用程序的运行过程中,内存管理是至关重要的,尤其是对于服务器端应用如Tomcat来说,内存配置的合理与否直接影响到应用的稳定性和性能。本文将针对...

    第25讲谈谈JVM内存区域的划分,哪些区域可能发生OutOfMemoryError1

    Java虚拟机(JVM)内存区域的划分是Java性能优化和...在实际开发中,合理设置JVM参数(如-Xms, -Xmx等)可以有效防止内存错误,同时,通过阅读如《深入理解Java虚拟机》等专业书籍,可以更深入地掌握JVM的内部机制。

    深入理解JVM-java虚拟机栈.docx

    如果虚拟机栈可以动态扩展,但扩展时无法获取足够的内存,会抛出`OutOfMemoryError`异常。大多数现代JVM允许动态扩展虚拟机栈的大小,但也允许固定大小的栈。 此外,栈帧中的变量槽在方法执行完成后可以复用,以...

Global site tag (gtag.js) - Google Analytics