博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java内存区域与模拟内存区域异常
阅读量:5810 次
发布时间:2019-06-18

本文共 2297 字,大约阅读时间需要 7 分钟。

我把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
list = new ArrayList
(); 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虚拟机中规范了两种异常:

  1. 假设线程请求的栈深度大于虚拟机所同意的最大深度,将抛出StackOverflowError异常。
  2. 假设虚拟机地扩展栈时无法申请到足够的内存空间,则抛出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。

你可能感兴趣的文章
servlet的简单操作
查看>>
shell脚本编程之条件测试——test
查看>>
被遗忘的Android mipmaps简介
查看>>
elk6+filebeat+kafka安装配置
查看>>
configparser的实践
查看>>
【20180408】MySQL集群PXC的一些随笔
查看>>
推荐10个很棒的AngularJS学习指南
查看>>
怀念回忆
查看>>
paramiko有密码和rsa方式无密码ssh、ftp
查看>>
J2SE之软件测试技术、单元测试以及日志管理器概念说明
查看>>
android DatabaseHelper
查看>>
Nginx+Redis+Ehcache:大型高并发与高可用的三层缓存架构总结
查看>>
JavaWeb系列:Servlet
查看>>
Python世界里的注释
查看>>
云MongoDB优化让LBS服务性能提升十倍
查看>>
PYTHON学习0004:数据类型----2019-6-4
查看>>
【unity实用技能】Unity画一条带箭头的线
查看>>
应用编排服务之ELK技术栈示例模板详解
查看>>
前后端分离框架介绍
查看>>
JVM-Class文件结构
查看>>