学习
实践
活动
工具
TVP
写文章

Java 内存溢出(OOM)异常完全指南

程序不能正常结束,事实,当我们使用如下参数启动程序时: java -Xmx100m -XX:+UseParallelGC Wrapper 我们很快就可以看到程序抛出java.lang.OutOfMemoryError 如果你限制了 JVM 可在用户空间创建线程数,那么你可以检查并增加这个限制: // macOS 10.12执行 $ ulimit -u 709 当你应用程序产生成千上万线程,并抛出此异常,表示你程序已经出现了很严重编程错误 原因分析 错误由 JVM 中 Native Code 抛出。 JVM 在为数组分配内存之前,会执行特定于平台检查:分配数据结构是否在此平台中是可寻址。 要理解你特定环境限制,运行下文中描述小测试程序程序尝试初始化数组大小在每次迭代时增加 1,最终达到Integer.MAX_VALUE。

1.4K01

如果你不了解JavaJVM,那真的很难进BAT一线大厂!

有人会说,这些写代码好像又用不,貌似所有的事情JVM都替我们做好了。那就,思考一下为什么要学习JVM虚拟机结构。 那你是否遇到这样困惑:堆内存设置多大? 欢迎大家关注我公种浩【程序员追风】,文章都会在里面更新,整理资料也会放在里面。 Java虚拟机规范规定,Java堆可以处于物理上不连续内存空间中,只要逻辑是连续即可。 也就是说堆内存是一块块拼凑起来。要增加堆空间时,往上“拼凑”(可扩展性)即可,但当堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。 如果线程请求栈深度大于虚拟机所允许深度,将抛出StackOverflowError异常;如果虚拟机栈动态扩展时无法申请到足够内存时会抛出OutOfMemoryError异常。 欢迎大家关注我公种浩【程序员追风】,文章都会在里面更新,整理资料也会放在里面。 方法返回:无论方法是否正常完成,都需要返回到方法被调用位置,程序才能继续进行。

16300
  • 广告
    关闭

    热门业务场景教学

    个人网站、项目部署、开发环境、游戏服务器、图床、渲染训练等免费搭建教程,多款云服务器20元起。

  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Java8内存结构改变~

    当栈调用深度大于JVM所允许范围,会抛出StackOverflowError错误,不过这个深度范围不是一个恒定值,我们通过下面这段程序可以测试一下这个结果: 栈溢出测试源码: ? 虚拟机栈除了上述错误外,还有另一种错误,那就是当申请不到空间时,会抛出 OutOfMemoryError。 JVM支持多个线程同时运行,每个线程都有自己程序计数器。倘若当前执行是 JVM 方法,则寄存器中保存当前执行指令地址;倘若执行是native 方法,则PC寄存器中为空。 当申请不到空间时会抛出 OutOfMemoryError。下面我们简单模拟一个堆内存溢出情况: ? 运行上述代码,输出结果如下:   ? 注意,这里我指定了堆内存大小为16M,所以这个地方显示count=14(这个数字不是固定),至于为什么会是14或其他数字,需要根据 GC 日志来判断,具体原因会在下篇文章中给大家解释。

    71920

    Java虚拟机详解(二)------运行时内存结构

    元数据区)来进行替代等等,关于这些区别本篇博客也会在文章末尾进行相应说明。 ③、不抛 OutOfMemoryError 异常   程序计数器空间大小不会随着程序执行而改变,始终只是保存一个 returnAdress 类型数据或者一个与平台相关本地指针值。 Java堆也是垃圾回收器管理主要区域。 ①、线程共享   堆存放对象,某个线程修改了对象属性,另外一个线程从堆中获取对象是修改后对象,为什么堆要设计成线程共享呢?    ④、抛出 OutOfMemoryError 异常   根据Java虚拟机规范,Java堆可以处于物理上不连续内存空间中,只要逻辑连续即可,实现时既可以实现成固定大小,也可以是扩展。 ②、抛出 OutOfMemoryError 异常   运行时常量池是方法区一部分,会受到方法区内存限制,当常量池无法申请到内存时,会抛出异常。

    36540

    10种常见OOM分析——手把手教你写bug

    ,除了程序计数器外,虚拟机内存其他几个运行时区域都有发生 OutOfMemoryError 异常可能。 执行了大量方法,导致线程栈空间耗尽 方法内声明了海量局部变量 native 代码有栈分配逻辑,并且要求内存还不小,比如 java.net.SocketInputStream.read0 会在要求分配一个 64KB 缓存(64位 Linux) 1.3 解决方案 修复引发无限递归调用异常代码, 通过程序抛出异常堆栈,找出不断重复代码行,按图索骥,修复无限递归 Bug 排查是否存在类之间循环依赖( GC,但只恢复了不到 2% 内存,且动作连续重复了 5 次,就会抛出 java.lang.OutOfMemoryError:GC overhead limit exceeded 错误(俗称:垃圾回收上头 面试官又来了:说一下 HashMap 原理以及为什么需要同时实现 equals 和 hashcode 执行这个程序最终错误,和 JVM 配置也会有关系,如果设置堆内存特别小,会直接报 Java heap

    36640

    JVM基础知识点Java内存模型

    程序计数器 是什么:程序计数器是很小一块内存空间,它是当前线程所执行字节码行号指示器。 有什么用:解释器通过这个计数器来选取下一条需要执行字节码指令。 为什么是线程共享:所有的线程都可以访问不同对象。 会出现什么异常情况:Java堆可以处于物理上不连续内存空间,但逻辑一定是连续,在堆中没有内存可以完成对象实例分配,且无法再扩展时,会抛出内存溢出异常。 Java虚拟机中描述了两种异常: 如果线程请求栈深度大于虚拟机所允许最大深度,将抛出StackOverflowError异常; 如果在虚拟机中无法申请到足够多内存空间,将抛出OutOfMemoryError 首先我们要分清楚产生OutOfMemoryError异常原因是内存泄露还是内存溢出,如果内存中对象确实都必须存活着而不像上面那样不断地创建对象实例却不使用对象,则是内存溢出,而像上面代码中情况则是内存泄露

    18520

    数据湖应用解析:Spark on Elasticsearch一致性问题

    执行了大量方法,导致线程栈空间耗尽 方法内声明了海量局部变量 native 代码有栈分配逻辑,并且要求内存还不小,比如 java.net.SocketInputStream.read0 会在要求分配一个 64KB 缓存(64位 Linux) 1.3 解决方案 修复引发无限递归调用异常代码, 通过程序抛出异常堆栈,找出不断重复代码行,按图索骥,修复无限递归 Bug 排查是否存在类之间循环依赖( GC,但只恢复了不到 2% 内存,且动作连续重复了 5 次,就会抛出 java.lang.OutOfMemoryError:GC overhead limit exceeded 错误(俗称:垃圾回收上头 面试官又来了:说一下 HashMap 原理以及为什么需要同时实现 equals 和 hashcode 执行这个程序最终错误,和 JVM 配置也会有关系,如果设置堆内存特别小,会直接报 Java heap : Requested array size exceeds VM limit JVM 限制了数组最大长度,错误表示程序请求创建数组超过最大长度限制。

    46720

    理解 OutOfMemoryError 异常

    另外,也有可能是在一些长时间运行程序中,可能是一直保持着对某些对象引用(实际这些对象已经不需要了),这会阻止垃圾回收器收集内存从而无法分配新内存空间。这就等同于是一个内存泄漏。 比如,如果程序尝试分配一个 512 MB 大小数组,但是堆大小最大只有 256MB,那么 OutOfMemoryError 异常则会被抛出。 如果抛出 OutOfMemoryErrorError 异常,则可能需要在操作系统使用故障排除实用程序来进一步诊断问题。 如果抛出此类 OutOfMemoryError 异常,则可能需要使用操作系统本机实用程序来进一步诊断问题。 这也就是 OutOfMemoryError 为什么排查起来比较困难,也比较难解决。

    11610

    常见 OOM 异常分析(硬核干货)

    执行了大量方法,导致线程栈空间耗尽 方法内声明了海量局部变量 native 代码有栈分配逻辑,并且要求内存还不小,比如 java.net.SocketInputStream.read0 会在要求分配一个 64KB 缓存(64位 Linux) 1.3 解决方案 修复引发无限递归调用异常代码, 通过程序抛出异常堆栈,找出不断重复代码行,按图索骥,修复无限递归 Bug 排查是否存在类之间循环依赖( GC,但只恢复了不到 2% 内存,且动作连续重复了 5 次,就会抛出 java.lang.OutOfMemoryError:GC overhead limit exceeded 错误(俗称:垃圾回收上头 面试官又来了:说一下HashMap原理以及为什么需要同时实现equals和hashcode 执行这个程序最终错误,和 JVM 配置也会有关系,如果设置堆内存特别小,会直接报 Java heap space kernel.pid_max(只能重启) native 内存不足;问题发生常见过程主要包括以下几步: JVM 内部应用程序请求创建一个新 Java 线程; JVM native 方法代理了次请求

    60110

    如何排查Java内存泄漏?看完我给跪了!

    为什么这些泄漏如此糟糕?除此之外,程序执行期间泄漏内存块通常会降低系统性能,因为分配但未使用内存块必须在系统耗尽空闲物理内存时进行换出。 最终,程序甚至可能耗尽其可用虚拟地址空间,从而导致OOM。 2. 解密OutOfMemoryError 如上所述,OOM是内存泄漏常见指示。实质,当没有足够空间来分配新对象时,会抛出错误。 实际,问题可能与配置问题一样简单。 例如,我负责分析一直产生这种类型OutOfMemoryError应用程序。 如果抛出此类型OOM,则可能需要在操作系统使用故障排除实用程序来进一步诊断问题。在某些情况下,问题甚至可能与应用程序无关。例如,您可能会在以下情况下看到此错误: 操作系统配置交换空间不足。 填充此空间时,GC会执行完整GC,这会在性能方面降低成本。如果此空间无限制地增长,则JVM将抛出OutOfMemoryError - Java堆空间。

    2.9K10

    如何排查Java内存泄漏?看完我给跪了!

    为什么这些泄漏如此糟糕?除此之外,程序执行期间泄漏内存块通常会降低系统性能,因为分配但未使用内存块必须在系统耗尽空闲物理内存时进行换出。 最终,程序甚至可能耗尽其可用虚拟地址空间,从而导致OOM。 2. 解密OutOfMemoryError 如上所述,OOM是内存泄漏常见指示。实质,当没有足够空间来分配新对象时,会抛出错误。 实际,问题可能与配置问题一样简单。 例如,我负责分析一直产生这种类型OutOfMemoryError应用程序。 如果抛出此类型OOM,则可能需要在操作系统使用故障排除实用程序来进一步诊断问题。在某些情况下,问题甚至可能与应用程序无关。例如,您可能会在以下情况下看到此错误: 操作系统配置交换空间不足。 填充此空间时,GC会执行完整GC,这会在性能方面降低成本。如果此空间无限制地增长,则JVM将抛出OutOfMemoryError - Java堆空间。

    48420

    Android 复习笔记(五)—— OutOfMemoryError 可以被 try catch 吗 ?

    Android 复习笔记目录 唠唠任务栈,返回栈和生命周期 唠唠 Activity 生命周期 扒一扒 Context 为什么不能使用 Application Context 显示 Dialog? 如果 Java 虚拟机栈支持动态扩展,当栈扩展时无法申请到足够内存会排抛出 OutOfMemoryError 异常。 本地方法栈。为虚拟机使用到 Native 方法服务。 本地方法栈也会在栈深度溢出和栈扩展失败时分别抛出 StackOverflowError 和 OutOfMemoryError 。 Java 堆。所有线程共享一块内存区域,在虚拟机启动时创建。 在 JDK 8 中,彻底废弃了永久代概念。 如果方法区无法满足新内存分配需求时,将抛出 OutOfMemoryError 。 运行时常量池。方法区一部分。 唯一一个在《Java虚拟机规范》中没有规定任何 OutOfMemoryError 情况区域是 程序计数器。

    22320

    异常、堆内存溢出、OOM几种情况

    当通过clone()接口去克隆一个对象,而对象对应类没有实现Cloneable接口,就会抛出CloneNotSupportedException异常。  被检查异常通常都是可以恢复。 按照Java惯例,我们是不应该是实现任何新Error子类! 对于上面的3种结构,我们在抛出异常或错误时,到底哪一种? OOM 1, OutOfMemoryError异常 除了程序计数器外,虚拟机内存其他几个运行时区域都有发生OutOfMemoryError(OOM)异常可能, Java Heap 溢出 一般异常信息 ,就会在对象数量达到最大堆容量限制后产生内存溢出异常。 如果虚拟机在扩展栈时无法申请到足够内存空间,则抛出OutOfMemoryError异常 这里需要注意当栈大小越大可分配线程数就越少。

    85640

    Java8内存模型—永久代(PermGen)和元空间(Metaspace)

    当栈调用深度大于JVM所允许范围,会抛出StackOverflowError错误,不过这个深度范围不是一个恒定值,我们通过下面这段程序可以测试一下这个结果: 栈溢出测试源码: package com.paddx.test.memory 至于红色框里值是怎么出来,就需要深入到 JVM 源码中才能探讨,这里不作详细阐述。 虚拟机栈除了上述错误外,还有另一种错误,那就是当申请不到空间时,会抛出 OutOfMemoryError。 JVM支持多个线程同时运行,每个线程都有自己程序计数器。倘若当前执行是 JVM 方法,则寄存器中保存当前执行指令地址;倘若执行是native 方法,则PC寄存器中为空。    当申请不到空间时会抛出 OutOfMemoryError。 注意,这里我指定了堆内存大小为16M,所以这个地方显示count=14(这个数字不是固定),至于为什么会是14或其他数字,需要根据 GC 日志来判断,具体原因会在下篇文章中给大家解释。

    22820

    Java8内存模型—永久代(PermGen)和元空间(Metaspace)

    当栈调用深度大于JVM所允许范围,会抛出StackOverflowError错误,不过这个深度范围不是一个恒定值,我们通过下面这段程序可以测试一下这个结果: 栈溢出测试源码: package com.paddx.test.memory 至于红色框里值是怎么出来,就需要深入到 JVM 源码中才能探讨,这里不作详细阐述。 虚拟机栈除了上述错误外,还有另一种错误,那就是当申请不到空间时,会抛出 OutOfMemoryError。 JVM支持多个线程同时运行,每个线程都有自己程序计数器。倘若当前执行是 JVM 方法,则寄存器中保存当前执行指令地址;倘若执行是native 方法,则PC寄存器中为空。 当申请不到空间时会抛出 OutOfMemoryError。 注意,这里我指定了堆内存大小为16M,所以这个地方显示count=14(这个数字不是固定),至于为什么会是14或其他数字,需要根据 GC 日志来判断,具体原因会在下篇文章中给大家解释。

    84420

    浅谈 Java 虚拟机内存区

    同样,当方法区无法满足内存分配需求时,会抛出 OutOfMemoryError。 上面的代码不断将字符串添加到常量池,最终肯定会导致内存不足,抛出方法区 OOM。解释一下,为什么必须将上面的代码在 JDK1.6 之前运行。 虚拟机栈特点 线程私有 生命周期与线程相同 虚拟机栈异常 一种是 StackOverflowError 当前线程如果请求栈深度大于虚拟机所允许深度时,则会抛出异常。 虚拟机规范中没有规定任何 OOM(OutOfMemoryError)情况区域 程序计算器作用 信号指示器:多线程间切换时,需恢复每一个线程的当前执行位置,通过程序计数器中值寻找要执行指令字节码 对于直接内存来说,JVM 将会在 IO 操作具有更高性能,因为它直接作用于本地系统 IO 操作。而堆内存如果要作 IO 操作,会先复制到直接内存,再利用本地 IO 处理。

    28310

    Java8内存模型—永久代(PermGen)和元空间(Metaspace)

    当栈调用深度大于JVM所允许范围,会抛出StackOverflowError错误,不过这个深度范围不是一个恒定值,我们通过下面这段程序可以测试一下这个结果: 栈溢出测试源码: package com.paddx.test.memory 至于红色框里值是怎么出来,就需要深入到 JVM 源码中才能探讨,这里不作详细阐述。 虚拟机栈除了上述错误外,还有另一种错误,那就是当申请不到空间时,会抛出 OutOfMemoryError。 JVM支持多个线程同时运行,每个线程都有自己程序计数器。倘若当前执行是 JVM 方法,则寄存器中保存当前执行指令地址;倘若执行是native 方法,则PC寄存器中为空。    当申请不到空间时会抛出 OutOfMemoryError。 ),至于为什么会是14或其他数字,需要根据 GC 日志来判断,具体原因会在下篇文章中给大家解释。

    7600

    内存溢出及解决方案

    什么是内存溢出 JVM运行过程中,程序不断申请内存空间用于保存运行时数据,当程序申请内存空间系统无法满足时,就会抛出内存溢出错误。 OutOfMemoryError是在程序无法申请到足够内存时候抛出异常。 StackOverflowError是线程申请栈深度大于虚拟机所允许深度所抛出异常。 OutOfMemoryError OutOfMemoryError是在程序无法申请到足够内存时候抛出异常,导致OutOfMemoryError异常常见原因有以下几种: 内存中加载数据量过于庞大 )不会在程序运行期对PermGen space进行清理。 因此,从根本上解决Java内存溢出唯一方法就是修改程序,及时地释放没用对象,释放内存空间。遇到错误时候要仔细检查程序。 码农架构-公众号.jpg

    40521

    内存溢出及解决方案

    什么是内存溢出 JVM运行过程中,程序不断申请内存空间用于保存运行时数据,当程序申请内存空间系统无法满足时,就会抛出内存溢出错误。 OutOfMemoryError是在程序无法申请到足够内存时候抛出异常。 StackOverflowError是线程申请栈深度大于虚拟机所允许深度所抛出异常。 OutOfMemoryError OutOfMemoryError是在程序无法申请到足够内存时候抛出异常,导致OutOfMemoryError异常常见原因有以下几种: 内存中加载数据量过于庞大 )不会在程序运行期对PermGen space进行清理。 因此,从根本上解决Java内存溢出唯一方法就是修改程序,及时地释放没用对象,释放内存空间。遇到错误时候要仔细检查程序

    33030

    异常、堆内存溢出、OOM几种情况

    当通过clone()接口去克隆一个对象,而对象对应类没有实现Cloneable接口,就会抛出CloneNotSupportedException异常。 被检查异常通常都是可以恢复。 按照Java惯例,我们是不应该是实现任何新Error子类! 对于上面的3种结构,我们在抛出异常或错误时,到底哪一种? OOM 1, OutOfMemoryError异常 除了程序计数器外,虚拟机内存其他几个运行时区域都有发生OutOfMemoryError(OOM)异常可能, Java Heap 溢出 一般异常信息 ,就会在对象数量达到最大堆容量限制后产生内存溢出异常。 如果虚拟机在扩展栈时无法申请到足够内存空间,则抛出OutOfMemoryError异常 这里需要注意当栈大小越大可分配线程数就越少。

    12010

    扫码关注腾讯云开发者

    领取腾讯云代金券