OOM异常的发生原因
一,jvm内存区域
1,程序计数器
一块很小的内存空间,作用是当前线程所执行的字节码的行号指示器。
2,java栈
与程序计数器一样,java栈(虚拟机栈)也是线程私有的,其生命周期与线程相同。通常存放基本数据类型,对象引用(一个指向对象起始地址的引用指针或一个代表对象的句柄),reeturnAddress类型(指向一条字节码指令的地址)
栈区域有两种异常类型:如果线程请求的栈深度大于虚拟机所允许的深度,将抛StrackOverflowError异常;如果虚拟机栈可以动态扩展(大部分虚拟机都可动态扩展),当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常。
3,本地方法栈
与虚拟机栈作用很相似,区别是虚拟机栈为虚拟机执行java方法服务,而本地方法栈则是为虚拟机用到的Native方法服务。和虚拟机栈一样可能抛出StackOverflowError和OutOfMemoryError异常。
4,java堆
java Heap是jvm所管理的内存中最大的区域。JavaHeap是被所有线程共享的一块内存区域,在虚拟机启动时创建。主要存放对象实例。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 的错误信息。
三,常见内存溢出错误解决办法
除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(OOM)异常的可能,
1,Java Heap 溢出
一般的异常信息:java.lang.OutOfMemoryError:Java heap spacess
java堆用于存储对象实例,我们只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,就会在对象数量达到最大堆容量限制后产生内存溢出异常。
出现这种异常,一般手段是先通过内存映像分析工具(如Eclipse Memory Analyzer)对dump出来的堆转存快照进行分析,重点是确认内存中的对象是否是必要的,先分清是因为内存泄漏(Memory Leak)还是内存溢出(Memory Overflow)。
如果是内存泄漏,可进一步通过工具(如Jrockit等工具)查看泄漏对象到GC Roots的引用链。于是就能找到泄漏对象时通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收。
如果不存在泄漏,那就应该检查虚拟机的参数(-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内存各部分OOM出现原因及解决方法(必看)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。
OOM异常的发生原因的更多相关文章
- OOM异常产生的原因和处理方法
一般而言,android中常见的原因主要有以下几个: 1.数据库的cursor没有关闭. 2.构造adapter没有使用缓存contentview. 3.调用registerReceiver()后未调 ...
- 真的可惜,四面阿里,结果我被JVM垃圾回收机制与 OOM异常卡住了
前言 为什么需要垃圾回收 首先我们来聊聊为什么会需要垃圾回收,假设我们不进行垃圾回收会造成什么后果,我们举一个简单的例子 我们住在一个房子里面,我们每天都在里面生活,然后垃圾都丢在房子里面,又不打扫, ...
- Android OOM异常解决方案
一,什么是OOM异常: OOM(out of Memory)即内存溢出异常,也就是说内存占有量超过了VM所分配的最大,导致应用程序异常终止: 二,为什么会产生OOM异常呢? OOM异常是Android ...
- JVM探究之 —— OOM异常
在Java虚拟机规范的描述中,除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(下文称OOM)异常的可能.本节探究主要基于jdk1.8的内存结构. 1. Jav ...
- java虚拟机(一)——内存管理机制与OOM异常
一 java内存区域与内存溢出异常(OOM) 1)运行时数据区域划分 1.程序计数器(Program Conuter Register) 程序计数器是一块较小的内存空间,它是当前线程执 ...
- 案例(1)-- OOM异常
问题描述: 1.系统在执行某个操作时,必现OOM异常. 问题的定位: 1.排查代码,未发现问题. 2.在虚拟机启动时,添加参数:-XX:+HeapDumpOnOutOfMemoryError(当发生o ...
- JVM OOM异常会导致JVM退出吗?
出处: https://mp.weixin.qq.com/s/8j8YTcr2qhVActLGzOqe7Q https://blog.csdn.net/h2604396739/article/de ...
- OOM异常的4种可能分析
OOM异常:OutOfMemoryError 1.JAVA堆溢出 JAVA堆用于存储对象实例,只要不断的创建对象,并且保证GC Roots到这些对象之间有路径可以来避免垃圾回收机制清除这些对象,那么在 ...
- 粘包、拆包发生原因滑动窗口、MSS/MTU限制、Nagle算法
[TCP协议](3)---TCP粘包黏包 [TCP协议](3)---TCP粘包黏包 有关TCP协议之前写过两篇博客: 1.[TCP协议](1)---TCP协议详解 2.[TCP协议](2)---TCP ...
随机推荐
- Sharing is only supported for boot loader classes because bootstrap classpath has been appended
在idea里面运行项目,terminal里面报“Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boo ...
- CentOS7安装CDH 第四章:CDH的版本选择和安装方式
相关文章链接 CentOS7安装CDH 第一章:CentOS7系统安装 CentOS7安装CDH 第二章:CentOS7各个软件安装和启动 CentOS7安装CDH 第三章:CDH中的问题和解决方法 ...
- c# 选择结构
- C 预编译 宏 声明
- django 新项目
1.创建虚拟环境 mkvirtualenv - p python3 2.pycharm : 在pycharm中新建项目, 取名.添加虚拟机上的虚拟环境
- 用js刷剑指offer(数值的整数次方)
题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 保证base和exponent不同时为0 牛客网链接 思路 快速幂算法,举个例 ...
- 【Leetcode】【简单】【1. 两数之和】【JavaScript】
题目描述 1. 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能 ...
- c/c++编译器配置(交叉编译重要参数)、交叉编译动态库与as配置、mk初步
gcc/g++/clang,相当于javac: 了解c/c++编译器的基本使用,能够在后续移植第三方框架进行交叉编译时,清楚的了解应该传递什么参数. clang: clang 是一个C.C++.Obj ...
- 【ecfinal2019热身赛】B题
原题: 给你一个长度为1e5的序列ai,问你它的所有子序列的最大值与最小值之差的1000次方的和是多少 即∑_{p是a的子序列}(max{p}-min{p})^1000 这题难点在于(max-min) ...
- 【转】go里面字符串转成 字节slice, 字节slice转成字符串
原文: https://yourbasic.org/golang/convert-string-to-byte-slice/#convert-string-to-bytes ------------- ...