JVM实战03(栈内存溢出)
目录
简介
对于虚拟机规范:
1.如果线程请求栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError。
2.如果虚拟机栈内存允许动态扩展,当无法申请到足够内存时,将抛出OutOfMemoryError。
Hotspot虚拟机特殊:
1.栈内存不可扩展。
2.不区分虚拟机栈和本地方法栈,可以统一用Xss参数设置栈的大小。
虚拟机栈
1.局部变量表
private void stackLeak()
{
long use1,use2,use3,use4,use5
.... //省略大量代码
}
假设stackLeak()方法里定义如上大量的局部变量use1,use2...
,那么由于局部变量是存放在栈帧里的局部变量表,如果定义了大量局部变量导致栈帧占用内存变大。
递归调用stackLeak()方法很不用调用几次就会出现栈内存溢出。
如何运行更多的线程?
假设有一台机子部署一个进程,该进程不断的创建新线程,机子当前内存支持最大创建5000个线程, 请问有什么办法在不改变机子内存的情况下让创建的线程数量增加?
1.栈是线程独享的:
所以如果减少栈的内存大小,通过减少Xss配置,那么相同内存的机子可以创建更多线程。
2.减少其它分配内存:
例如:堆内存,方法区,程序计数器...
3.尽量杀死其它程序
4.操作系统会限制最大线程数量,适当修改配置:
例如linux下:
cat /proc/sys/kernel/pid_max //查看系统限制某用户下最多可以运行多少进程或线程。