博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JVM学习笔记三_异常初步
阅读量:5253 次
发布时间:2019-06-14

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

Java堆溢出

说明:Java堆用于存储对象实例,只要不断创建对象。且保证GC Roots到对象之间有可达的路径来避免垃圾回收机制来清除这些对象,那么在对象数量达到最大堆的容量限制之后就会产生内存溢出异常。

重点:模拟不断创建对象简单,但是需要保证创建出来的对象不被GC掉。同样的,出错时可能的状况也是如此,就是对象被创建出但是未被及时回收。-Xms堆最小值 -Xmx堆最大值。

虚拟机栈和本地方法栈溢出

抛出两种异常:

1. 如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。

2. 如果虚拟机在扩展栈时,无法申请到足够的内存空间,则抛出OutOfMemoryError异常。

说明:单线程的情况下,不论是栈帧太大还是虚拟机的栈内存太小,当内存无法正常分配时,都会抛出StackOverflowError异常。

      但是如果在使用多线程的情况下,会产生OutOfMemoryError异常。每个线程不断去创建线程,那么当到达上限是,就会抛出OutOfMemoryError异常。而且栈帧越大,线程上限将会越小。

   原因就是:操作系统对于每个进程,分配的内存都是有限制的。虚拟机参数控制了Java堆和方法区的内存的最大值。所以剩余内存为 进程分配的最大内存(M) 减去 最大堆的内存Xmx,再减去最大方法区的MaxPermSize,

   程序计数器内存很小可忽略。剩下的内存是由虚拟机栈和本地方法栈分得的。每个线程分配到的栈容量越大,那么可建立的线程数量就会很小,建立线程时就会越容易把内存耗尽。

一般情况下 栈深度可以达到1000到2000。但是如果建立了过多的线程导致了内存溢出,在不能减少线程和使用64位虚拟机的情况下,只能通过减少最大堆和减少栈容量来换取更多线程。

 方法区和运行时常量区溢出

 运行时常量池是方法区的一部分,在JDK1.6及以前的版本中,因为常量池分配在永久代中,我们可以通过-XX:PermSize和-XX:MaxPermSize来限制方法区大小,从而间接限制其中常量池的容量。

 代码如下:

1 public static void main(String[] args) {2     List
list = new ArrayList
();3 int i = 1;4 while (true) {5 ist.add(String.valueOf(i++).intern());6 }7 }

会抛出OutOfMemoryError异常。

但是在JDK1.7以后,while循环会一直进行下去。

方法区的用于存储Class相关的信息,比如类名、访问修饰符、常量池、字段描述、方法描述等。对于此区域的测试,可以产生大量的类去填满方法区,直到溢出。

转载于:https://www.cnblogs.com/kawin/p/10017379.html

你可能感兴趣的文章
Paper Reading: Relation Networks for Object Detection
查看>>
day22 01 初识面向对象----简单的人狗大战小游戏
查看>>
mybatis源代码分析:深入了解mybatis延迟加载机制
查看>>
Flask三剑客
查看>>
Hibernate-缓存
查看>>
【BZOJ4516】生成魔咒(后缀自动机)
查看>>
提高PHP性能的10条建议
查看>>
svn“Previous operation has not finished; run 'cleanup' if it was interrupted“报错的解决方法...
查看>>
熟用TableView
查看>>
Java大数——a^b + b^a
查看>>
poj 3164 最小树形图(朱刘算法)
查看>>
服务器内存泄露 , 重启后恢复问题解决方案
查看>>
android一些细节问题
查看>>
KDESVN中commit时出现containing working copy admin area is missing错误提示
查看>>
利用AOP写2PC框架(二)
查看>>
【动态规划】skiing
查看>>
java定时器的使用(Timer)
查看>>
ef codefirst VS里修改数据表结构后更新到数据库
查看>>
boost 同步定时器
查看>>
[ROS] Chinese MOOC || Chapter-4.4 Action
查看>>