Java内存区域与模拟内存区域异常
我把Java的内存区域画了一张思维导图,以及各区域的主要功能。
模拟Java堆溢出
Java堆用于存储对象实例。仅仅要不断地创建对象而且保证GC ROOTS到对象之间有可达路径避免被回收机制清除。就能够模拟出Java堆溢出。
package hxl.insist.jvm;
import java.util.ArrayList;
import java.util.List;
/**
* 以下是JVM Args:
* -Xms20m 堆的最小值 -Xmx20m 堆的最小值 (设置为一样可避免堆自己主动扩展)
* -XX:+HeapDumpOnOutOfMemoryError 当虚拟机出现内存溢出异常时,Dump出当前的堆转储快照
* -XX:HeapDumpPath=E:\eclipseworkspace\UnderStandingTheJVM\hprof 设置生成的堆转储快照的路径
* @author hanxl
*
*/
public class HeapOutOfMemory {
static class StuffObject {
}
static List<StuffObject> list = new ArrayList<StuffObject>();
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
public void run() {
createObj();
}
});
thread.start();
}
private static void createObj() {
while (true) {
list.add(new StuffObject());
}
}
}
用MemoryAnalyzer分析一下堆转储快照例如以下图:
从根元素到内存消耗聚集点的最短路径,能够非常清楚的看到整个引用链。
在上面这张图上,我们能够清楚的看到,这个对象集合中保存了大量内部类StuffObject 对象的引用,就是它导致的内存泄露。
模拟Java虚拟机栈溢出
关于虚拟机栈,在Java虚拟机中规范了两种异常:
- 假设线程请求的栈深度大于虚拟机所同意的最大深度,将抛出StackOverflowError异常。
- 假设虚拟机地扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。
模拟第一种情况:
package hxl.insist.jvm;
/**
* 以下是JVM Args:
* -Xss128k 设置栈容量大小
* @author hanxl
*/
public class JavaVMStackSOF {
public void stackLeak() {
stackLeak();
}
public static void main(String[] args) throws Throwable {
new JavaVMStackSOF().stackLeak();
}
}
模拟另外一种情况:
package hxl.insist.jvm;
/**
* 以下是JVM Args:
* -Xss2M 设置栈容量大小
* @author hanxl
*/
public class JavaVMStackOOM {
public static void main(String[] args) {
new JavaVMStackOOM().threadInvokeMethod();
}
public void threadInvokeMethod() {
while (true) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
infiniteLoop();
}
});
thread.start();
}
}
private void infiniteLoop() {
while (true)
;
}
}
比較两种情况为什么实现方式不同?
Java虚拟机栈是线程私有的,它的生命同期与线程同样。我们把虚拟机栈比做一个盒子,-Xss是设置盒子的大小,而一个线程仅仅能相应一个盒子。而每一个Java方法在运行的时候都会在盒子中创建一个栈帧用于存储局部变量表等一些信息。
所以为了制造出第一种情况下的异常,我们把盒子的大小设置小一点,使用递归不断调用方法,从而撑破盒子。而为了制造出另外一种情况下的异常,我们应该把盒子的大小设置小大一点,多创建一些盒子,从而让其无法申请到足够的内存空间。
仅仅要了解上面那张思维导图的内存区域,模拟出其他内存区域异常也非常easy。
Java内存区域与模拟内存区域异常的更多相关文章
- Java内存区域-- 运行时数据区域
jvm在执行Java程序时,会把它所管理的内存划分为若干个不同的数据区.这些区域都有各自的用途,以及创建和销毁的时间. 有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销 ...
- Java内存管理原理及内存区域详解
一.概述 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干不同的数据区域,这些区域都有各自的用途以及创建和销毁的时间.Java虚拟机所管理的内存将会包括以下几个运行时数据区域,如下 ...
- Java内存管理以及各个内存区域详解
一.概述 原文链接:http://blog.csdn.net/l271640625/article/details/39761439 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若 ...
- 深入理解Java虚拟机读书笔记1----Java内存区域与HotSpot虚拟机对象
一 Java内存区域与HotSpot虚拟机对象 1 Java技术体系.JDK.JRE? Java技术体系包括: · Java程序设计语言: · 各种硬件平台上的 ...
- Java的内存管理机制之内存区域划分
各位,好久不见.先做个预告,由于最近主要在做Java服务端开发,最近一段时间会更新Java服务端开发相关的一些知识,包括但不限于一些读书笔记.框架的学习笔记.和最近一段时间的思考和沉淀.先从Java虚 ...
- Java内存区域划分、内存分配原理(转)
文章引用自 http://blog.csdn.net/OyangYujun/article/details/41173747 运行时数据区域 Java虚拟机在执行Java的过程中会把管理的内存划分为若 ...
- Java内存区域划分、内存分配原理(深入理解JVM一)
Java虚拟机在执行Java的过程中会把管理的内存划分为若干个不同的数据区域.这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,而有的区域则依赖线程的启动和结束而创建和销 ...
- java内存结构(执行时数据区域)
java虚拟机规范规定的java虚拟机内存事实上就是java虚拟机执行时数据区,其架构例如以下: 当中方法区和堆是由全部线程共享的数据区. Java虚拟机栈.本地方法栈和程序计数器是线程隔离的数据区. ...
- Java内存区域(运行时数据区域)和内存模型(JMM)
Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数据分区域存储,强调对内存空间的划分. 而内存模型(Java Memory Model,简称 JMM )是定义了线程和主内存之 ...
随机推荐
- (转载)django 访问url报错Forbidden (CSRF cookie not set.): xxx 问
原地址:http://www.cnblogs.com/meitian/p/7016336.html 问题:页面访问时报错 Forbidden (CSRF cookie not set.): xxx ...
- POJ 2836:Rectangular Covering(状态压缩DP)
题目大意:在一个平面内有若干个点,要求用一些矩形覆盖它们,一个矩形至少覆盖两个点,可以相互重叠,求矩形最小总面积. 分析: 数据很小,很容易想到状压DP,我们把点是否被覆盖用0,1表示然后放在一起得到 ...
- BZOJ3571 [Hnoi2014]画框 【分治 + KM算法】
题目链接 BZOJ3571 题解 如果知道最小乘积生成树,那么这种双权值乘积最小就是裸题了 将两权值和作为坐标,转化为二维坐标系下凸包上的点,然后不断划分分治就好了 这里求的是最小匹配值,每次找点套一 ...
- 【转】 #define用法详解
#define用法详解 1.#define 的作用 在C或C++语言源程序中允许用一个标识符来表示一个字符串,称为“宏”.被定义为“宏”的标识符称为“宏名”.在编译预处理时,对程序中所有出现的“宏 ...
- 【12】vue-router 之路由重定向
看之前的项目,突然发现一个不算bug的bug,之前也是一直没有想到,现在发现之后越来越觉得有必要改掉, 项目用的是vue做的,自然切换用的就是路由,一级路由包括:首页.记录和个人中心,二级路由是在记录 ...
- USACO 刷题记录bzoj
bzoj 1606: [Usaco2008 Dec]Hay For Sale 购买干草——背包 #include<cstdio> #include<cstring> #incl ...
- EnableViewState 属性
原文发布时间为:2009-10-25 -- 来源于本人的百度文章 [由搬家工具导入] 指示是否在页请求之间保持视图状态。如果要保持视图状态,则为 true;否则为 false。默认值为 true。 自 ...
- java中Map的entrySet 和keySet的使用
存储这样的一个数据关系结构 使用嵌套map存储 可以通过调用 entrySet方法 或者 keySet方法 进行迭代或者增强for循环 便利输出 这里演示 迭代器的方式进行遍历 package ...
- python-rtslib 模块
Python library for configuring the Linux kernel-based multiprotocol SCSI target (LIO) A Python objec ...
- hdu 4859(思路题)
Goffi and Squary Partition Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...