JVM—内存溢出、OutOfMemoryError、StackOverflowError
学习jvm时看到几篇非常好的系列文章,转载了:
一、概要
我们可以带着以下几个问题去学习自动内存管理机制,罗列如下:
- 什么操作可能导致内存溢出?
- 有哪些种类的内存溢出?
- 都是在内存的哪些区域溢出?
二、运行时数据区域
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,如下图所示
其中虚拟机栈、本地方法栈和程序技术器是线程私有的,方法区和堆是线程共享的.
2.1程序计数器
作用:当前线程所执行的字节码的行号指示器
- 字节码解释器工作时通过改变它的值来选取下一条需要执行的字节码指令
- 分支、循环、跳转、异常处理和线程恢复都依赖于它
2.2虚拟机栈
栈的作用:栈用于存储局部变量表、操作数栈、动态链接和方法出口等信息.
其中局部变量表用于存放8种基本数据类型(boolean,byte,char,short,int,float,long,double)和reference类型.
reference类型:
指向对象起始地址的引用指针
指向一个代表对象的句柄
指向一条字节码指令的地址
可抛出两种异常状况
线程请求的栈深度大于虚拟机所允许的栈深度,抛出StackOverflowError异常
当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常是
2.3本地方法栈
与虚拟机栈的作用非常相似.其区别是虚拟机栈执行Java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务
同时也会抛出StackOverflowError和OutOfMemoryError异常
2.4堆
堆的作用:分配所有的对象实例和数组。可以抛出OutOfMemoryError异常。
2.5方法区
方法区的作用:用于存储已被虚拟机加载的类信息(Class)、常量(final修饰)、静态变量(static)和即时编译器编译后的代码(code)
可以抛出OutOfMemoryError异常
2.6运行时常量池
属于方法区的一部分,用于存放编译期生成的各种字面量和符号引用(在以后介绍Class结构会讲到),在类加载后存放到方法区的运行时常量池中。可抛出OutOfMemoryError异常
三、对象访问
主流的两种访问方式:使用句柄和直接指针。(HotSpot虚拟机就是使用直接指针的访问方式)
使用句柄访问
四、OutOfMemoryError异常
在Java虚拟机规范的描述中,除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError异常的可能.
下面通过若干实例来验证异常发生的场景.以下代码的开头都注释了执行时所需要设置的虚拟机启动参数,这些参数对实验结果有直接影响,请调试代码的时候不要忽略掉.
4.1Java堆溢出
堆里放的是new出来的对象,所以这部分很简单不断的new对象就可以了,但是为了防止对象new出来之后被GC,所以把对象new出来的对象放到一个List中去即可。为了有更好的效果,可以在运行前,调整堆的参数。
- import java.util.ArrayList;
- import java.util.List;
- /**
- * VM Args: -Xms20m -Xms20m - XX:+HeapDumpOnOutOfMemoryError
- * @author Administrator
- *
- */
- public class HeapOOM {
- static class OOMObject{}
- public static void main(String[] args) {
- List<OOMObject> list = new ArrayList<HeapOOM.OOMObject>();
- while(true ){
- list.add( new OOMObject());
- }
- }
- }
运行结果
4.2虚拟机栈溢出
- 在单线程的堆中我们不断的让一个成员变量自增,容纳这个变量的单元无法承受这个变量了,就抛出StackOverflowError了。
- 可以开尽量多的线程,并在每个线程里调用native的方法,就自然会抛出 OutOfMemoryError了。
- /**
- * VM Args: - Xss64k
- * @author Administrator
- *
- */
- public class JavaVMStackSOF {
- private int stackLength = 1;
- public void stackLeak(){
- stackLength ++;
- stackLeak();
- }
- public static void main(String[] args) throws Throwable {
- JavaVMStackSOF oom = new JavaVMStackSOF();
- try{
- oom.stackLeak();
- } catch(Throwable e){
- System. out.println("Stack length:" + oom.stackLength);
- throw e;
- }
- }
- }
运行结果
- import java.lang.reflect.Method;
- import net.sf.cglib.proxy.MethodInterceptor;
- import net.sf.cglib.proxy.Enhancer;
- import net.sf.cglib.proxy.MethodProxy;
- /**
- * VM Args:- XX:PermSize=10m -XX:MaxPermSize=10m
- * @author Administrator
- *
- */
- public class JavaMethodAreaOOM {
- public static void main(String[] args) {
- while (true ){
- Enhancer enhancer = new Enhancer();
- enhancer.setSuperclass(OOMObject. class );
- enhancer.setUseCache( false );
- enhancer.setCallback( new MethodInterceptor() {
- @Override
- public Object intercept(Object obj, Method method, Object[] args,
- MethodProxy proxy) throws Throwable {
- return proxy.invoke(obj, args);
- }
- });
- enhancer.create();
- }
- }
- static class OOMObject{
- }
- }
4.4 运行时常量池溢出
- import java.util.ArrayList;
- import java.util.List;
- /**
- * VM Args:- XX:PermSize=10m -XX:MaxPermSize=10m
- * @author Administrator
- *
- */
- public class RuntimeConstantPoolOOM {
- public static void main(String[] args) {
- List<String> list = new ArrayList<String>();
- int i = 0;
- while (true ){
- list.add(String. valueOf(i++).intern());
- }
- }
- }
相关引用:
JVM—内存溢出、OutOfMemoryError、StackOverflowError的更多相关文章
- JVM内存溢出分析java.lang.OutOfMemoryError: Java heap space
JVM内存溢出查询java.lang.OutOfMemoryError: Java heap space查出具体原因分为几个预备步骤 1.在运行java程序是必须设置jvm -XX:+HeapDump ...
- jvm内存溢出分析
概述 jvm中除了程序计数器,其他的区域都有可能会发生内存溢出 内存溢出是什么? 当程序需要申请内存的时候,由于没有足够的内存,此时就会抛出OutOfMemoryError,这就是内存溢出 内存溢出和 ...
- jvm内存溢出问题
Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出 J ...
- jvm 内存溢出问题排查方法
如果你做TCP通讯或者map集合操作,并发处理等功能时,很容易出现 Java 内存溢出的问题.本篇文章,带领大家深入jvm,分析并找出jvm内存溢出的代码. jvm中除了程序计数器,其他的区域都有可能 ...
- JVM 内存溢出详解(栈溢出,堆溢出,持久代溢出、无法创建本地线程)
出处: http://www.jianshu.com/p/cd705f88cf2a 1.内存溢出和内存泄漏的区别 内存溢出 (Out Of Memory):是指程序在申请内存时,没有足够的内存空间供 ...
- JVM 内存溢出 实战 (史上最全)
文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...
- Tomcat中JVM内存溢出及合理配置及maxThreads如何配置(转)
来源:http://www.tot.name/html/20150530/20150530102930.htm Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个Java虚 ...
- Tomcat中JVM内存溢出及合理配置
Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个Java虚拟机.Tomcat的内存溢出本质就是JVM内存溢出,所以在本文开始时,应该先对Java JVM有关内存方面的知识 ...
- JVM内存溢出及合理配置
Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个Java虚拟机.Tomcat的内存溢出本质就是JVM内存溢出,所以在本文开始时,应该先对Java JVM有关内存方面的知识 ...
- 巧解Tomcat中JVM内存溢出问题
你对Tomcat 的JVM内存溢出问题的解决方法是否了解,这里和大家分享一下,相信本文介绍一定会让你有所收获. tomcat 的JVM内存溢出问题的解决 最近在熟悉一个开发了有几年的项目,需要把数据库 ...
随机推荐
- SharePonit online 列表表单定制
1)在O365管理中心,确保启用了站点脚本定制,否则,网站不允许将页面切换到编辑模式. 2)Ribbon上,列表->表单web部件->编辑窗体 如果没有Ribbon,则到列表高级设置,启用 ...
- iOS实现pdf文件预览,上下翻页、缩放,读取pdf目录
最近有个朋友想做一个pdf预览,要求能够上下滑动翻页.带缩放.目录跳转功能. 因为之前我只做过简单的预览,那时直接用uiwebview实现的,这次找了下资料,发现一个比较好的库. 其原理实现: 自定义 ...
- 先从一个 libev 的 demo 入手
最近想研究下 libev 这个网络库,所以先从官方文档一个最简单的 demo 开始,代码如下: //io.c // a single header file is required #include ...
- fgrep: ifcfg-ifcfg-eth0: No such file or directory
[root@localhost ~]# service network restartfgrep: ifcfg-ifcfg-eth0: No such file or directoryfgrep: ...
- GPL、BSD、MIT、Mozilla、Apache、LGPL开源协议介绍
BSD开源协议 BSD开源协议是一个给于使用者很大自由的协议.基本上使用者可以”为所欲为”,可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布. 但”为所欲为”的前提当你发布使 ...
- linux内核剖析(九)进程间通信之-信号signal
信号及信号来源 什么是信号 信号是UNIX和Linux系统响应某些条件而产生的一个事件,接收到该信号的进程会相应地采取一些行动.通常信号是由一个错误产生的.但它们还可以作为进程间通信或修改行为的一种方 ...
- 【20180409】IT管理之IT十二条令
团队越来越大,靠人管几乎有力无心,只能靠制度管理了. 前段时间对部门颁布了12条令,效果明显. 特此Mark. 汇报: 三条总结:汇报讲究精简,一个事情最多一句话概括. 一页报告:内容精简,报告一页w ...
- (10) 如何MySQL读压力大的问题
如何进行读写分离 由开发人员根据所执行的SQL类型连接不同的服务器 由数据库中间层实现读写分离 读写分离时,需要注意,对于实时性要求比较高的数据,不适合在从库上查询(因为主从复制存在一定延迟(毫秒级) ...
- Nginx SSL 结合Tomcat 重定向URL变成HTTP的问题
http://www.siven.net/posts/d925bb5d.html *********************************************** 问题描述 由于要配置服 ...
- python faker 生成随机类型字符串
以前生成测试字符时,用random模块拼来拼去来生成随机串,如姓名,手机,身份证等,还是费一些功夫,不过有了faker模块,一切变得简单起来 基本使用: from faker import Faker ...