文章目录
- SOFE之stackoverflowError
- OOM之java heap space
- OOM之GC overhead limit exceeded
- OOM之Direct buffer memoery
- OOM之unable to create new native thread
- OOM之unable to create new native thread解决方案
- OOM之metaspace
SOFE之stackoverflowError
首先stackoverflowError是错误,不是异常。
最简单的出发SOFE的操作,无限循环递归调用:
错误提示:
栈中压入了太多的方法给撑爆了,栈大小根据平台有默认值,linux内核的一般是1024k,win系统默认是0。复习一下java异常的体系结构:
查看SOFE的的继承树:属于虚机机error
oom也是虚拟机错误。
OOM之java heap space
简单理解:堆内存不够用了。
触发代码如下,但是因为jvm在win平台上默认最大堆空间是内存的四分之一,所以很难撑爆,需要手动调小一点(10m)。
string的方法intern
错误效果:
直接new 字节数组,也可以,方法很多。
OOM之GC overhead limit exceeded
大量的资源被消耗来做垃圾回收,有用的工作只占很少的一部分。
代码演示:不断往list中添加string(不重复)
为了触发效果调整jvm参数:堆大小10m,降低直接内存的大小为5m。运行效果:运行几秒之后,会触发gc overhead的异常。
可以看到爆发异常前产生了full gc,回收前后的young区大小差别不大2047—2047.出现了收不动的现象,老年区也是同样的现象。
OOM之Direct buffer memoery
这个错误跟元空间有关系,元空间使用的是本地内存:
这个错误,意思是把你的直接内存都干翻了!
这个故障结合2种技术出现:netty底层的nio技术。
那么如何查看分配的直接内存的情况呢?在rt.jar包里面。
做一个测试,针对16g电脑,直接电脑能利用的有:
内存分配模型:
触发Direct buffer memoery OOM异常的代码如下,需要配置一下vm参数:
运行效果:
会发现最后一次full gc收不动了,一般做nio程序的时候经常出现这个异常。这个异常反映了你是否知道nio。
OOM之unable to create new native thread
不能创建更多新的本地线程了。高并发环境下容易触发这个错,因为高并发往往需要创建多线程。
因为一个系统中的线程数是有上限的。超过上限就报错误。
这个异常是一个非常好的案例作为回答面试官的“说一下你的记忆深刻的故障”。
触发代码:
linux上试运行,注意如果带包名的java文件,需要"-d ."这种参数。
没有消息就是编译成功了。运行需要带包名:
会发现大约在1024个以内就抛出异常了。1024是理论数字,linux进程本身句柄也需要一些线程。
OOM之unable to create new native thread解决方案
会发现root用户无上限,但是普通用户有1024的限制。
OOM之metaspace
场景解释:
代码触发:
使用spring的动态字节码技术,不停的创建一个类。不停的生成模板不停的加载。
运行结果: