Java 出现内存溢出的定位以及解决方案

在上一节中Java虚拟机内存分布  
说了Java虚拟机中分为五个区域,而且也知道了在Java程序计数器区域不会出现OOM(OutOfMemeryError),那么以下就对除了程序计数器以外的四个区域出现OOM的原理以及解决方案进行解说。

1.Java虚拟机栈与本地方法栈

栈的大小控制參数时 -Xss。

Java虚拟机在栈中定义了两种异常,StrackOverFlowError和OutOfMemeryError。当请求栈的深度大于java虚拟机所同意的最大深度则抛出StrackOverFlowError;假设Java虚拟机在栈扩展时。没有申请到足够的空间时,则抛出OutOfMemeryError。

StrackOverFlowError:Java虚拟机在执行中,调用方法时,都要创建栈帧,当栈的空间不够时就会产生StrackOverFlowError。那么相应的解决方法就仅仅能是调节-Xss參数,或者降低方法的调用,减小栈帧的大小两种方式。

OutOfMemeryError:在栈上出现OOM通常是多线程的情形。

首先咋们解析一下栈使用的空间能够有多大,拿32位操作系统来举例。 最大内存2G - Xmx(最大堆容量)- MaxPermSize(最慷慨法区容量)- 虚拟机本身耗费的内存和程序计数器使用的内存。

剩下的内存就是栈能够使用的空间,当Xss配置的參数一定时,那么在不断的创建线程过程中。遇到不能申请到栈空间的时候就会抛出OOM。那么相应的解决方案就是,调节-Xss參数减少栈大小,或者调节-Xmx以及MaxPermSize的大小扩大留给栈的空间。

2.方法区内存溢出

方法区的大小通过-PermSize和-MaxPermSize控制。

由于类常量和执行时常量也存储在方法区中,所以执行时常量过多也可导致方法区的OOM,可是没有直接控制常量池大小的參数,仅仅能通过-PermSize和-MaxPermSize来间接控制。

在Spring以及Hibernate。Mybatis中都会使用GeneratedConstructorAccessor、动态代理以及CGLib字节码增强技术的等动态生成类,那么就须要强大的方法区来支撑。

3.堆内存的溢出

堆内存的溢出比較复杂,须要调节GC等多种參数,我们在后面的章节中会进行解说。

时间: 2024-08-24 22:54:43

Java 出现内存溢出的定位以及解决方案的相关文章

Java 出现内存溢出的定位以及解决方式

在上一节中Java虚拟机内存分布   说了Java虚拟机中分为五个区域,并且也知道了在Java程序计数器区域不会出现OOM(OutOfMemeryError),那么下面就对除了程序计数器以外的四个区域出现OOM的原理以及解决方式进行讲解. 1.Java虚拟机栈与本地方法栈 栈的大小控制参数时 -Xss. Java虚拟机在栈中定义了两种异常,StrackOverFlowError和OutOfMemeryError.当请求栈的深度大于java虚拟机所允许的最大深度则抛出StrackOverFlowE

[转]Java内存溢出详解及解决方案

原文地址:http://blog.csdn.net/xianmiao2009/article/details/49254391 内存溢出与数据库锁表的问题,可以说是开发人员的噩梦,一般的程序异常,总是可以知道在什么时候或是在什么操作步骤上出现了异常,而且根据堆栈信息也很容易定位到程序中是某处出现了问题.内存溢出与锁表则不然,一般现象是操作一般时间后系统越来越慢,直到死机,但并不能明确是在什么操作上出现的,发生的时间点也没有规律,查看日志或查看数据库也不能定位出问题的代码. 更严重的是内存溢出与数

【转】Java学习---内存溢出的排查经历

[原文]https://www.toutiao.com/i6595365358301872643/ 前言 OutOfMemoryError 问题相信很多朋友都遇到过,相对于常见的业务异常(数组越界.空指针等)来说这类问题是很难定位和解决的. 本文以最近碰到的一次线上内存溢出的定位.解决问题的方式展开:希望能对碰到类似问题的同学带来思路和帮助. 主要从表现-->排查-->定位-->解决 四个步骤来分析和解决问题. 表象 最近我们生产上的一个应用不断的爆出内存溢出,并且随着业务量的增长出现的

关于java堆内存溢出的几种情况(转)

[情况一]: java.lang.OutOfMemoryError: Java heap space:这种是java堆内存不够,一个原因是真不够,另一个原因是程序中有死循环: 如果是java堆内存不够的话,可以通过调整JVM下面的配置来解决: <jvm-arg>-Xms3062m</jvm-arg> <jvm-arg>-Xmx3062m</jvm-arg> [情况二] java.lang.OutOfMemoryError: GC overhead limit

记一次java程序内存溢出问题

一个自然语言处理程序,在封装为web-service后,部署到线上运行. 但最近出现了内存溢出的情况,频繁的out of memory. 先盲目尝试在启动脚本中增加-XX:-UseGCOverheadLimit. 因为根据原因未找到,依然频繁的out of memory,只能一直观察jstat -gcutil <pid>,看到老生代内存降不下来时,重启程序. 服务程序很简单,简单接收参数,自然语言处理,返回数据,除了自然语言处理模块,都是方法参数,不会出现内存泄漏的情况. 第一次解决这种内存溢

java常见内存溢出情形

虚拟机栈溢出(如果虚拟机在扩展时无法申请到足够的内存空间将抛出OutOfMemoryError) package com.jvm.memory; import java.util.ArrayList; import java.util.List; public class HeapOOM { /** * VM 运行时参数 -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError * @param args */ public static void main

java常见内存溢出(OOM)

jvm内存区域 程序计数器一块很小的内存空间,作用是当前线程所执行的字节码的行号指示器. java栈与程序计数器一样,java栈(虚拟机栈)也是线程私有的,其生命周期与线程相同.通常存放基本数据类型,对象引用(一个指向对象起始地址的引用指针或一个代表对象的句柄),reeturnAddress类型(指向一条字节码指令的地址) 栈区域有两种异常类型:如果线程请求的栈深度大于虚拟机所允许的深度,将抛StrackOverflowError异常:如果虚拟机栈可以动态扩展(大部分虚拟机都可动态扩展),当扩展

java虚拟机内存溢出各种场景总结

java堆溢出 java堆用于存储对象实例,只要不断地创建对象,并且保证gc roots到对象之间有可达路径来避免垃圾回收机制来清楚这些对象,那么在 对象到达最大堆的容量限制后就会产生内存溢出溢出. 异常:java.lang.OutOfMemoryError: java heap space 要解决这个区域的异常,首先要区分是出现了内存泄露(Memory Leak)还是内存溢出(Memory OverFlow). 解决方式:如果是内存泄露,通过工具(eclipse memory analyzer

Java虚拟机-内存溢出异常

内存泄露与内存溢出 内存泄露一般是代码设计存在缺陷导致的,指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存.即被分配的对象可达但是已经无用:通过了解内存泄露的场景,可以避免不必要的内存溢出和提高自己的代码水平: 内存泄露的几种场景:1.长生命周期的对象持有短生命周期对象的引用      例如:在全局静态map中缓存局部变量,且没有清空操作,随着时间的推移,这个map会越来越大,造成内存泄露:2.修改hashset中对象的参数值,且参数是计算哈希值的字段     当一个