jvm内存区域
方法区(Method Area) | 常量池(Run-Time Constant Pool) | 堆(Heap |
---|---|---|
程序计数器(Program Counter) | 虚拟机栈(Java Virtual Machine Statcks) | 本地方法栈(Native Method Stacks) |
方法区(Method Area)
存储class类型、常量、静态变量、即时编译后的代码等数据。各个线程共享区域。
常量池(Run-Time Constant Pool):常量池属于方法区,存储常量和在编译期生成的各种字面量和符号引用。
可能抛异常:
OutOfMemeoryError
原因
如果需要在方法区(PermGen)申请分配内存请求时,此时方法区(PermGen)内存不够,则抛出OutOfMemoryError。
通常是:
- jsp页面或通过CGLib、OSGI动态生成大量的类,有可能导致PermGen space内存不足。
- 是由于使用String.intern()方法添加了过多内容。
解决方法:
- 检查是否使用String.intern()添加了过多内空,
- 增大 -X:MaxPermSize 参数值。class也可以回收的,参数:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled 。但不建议这样种。
堆(Heap)
存储所有对象和数组实例。
可能抛异常
OutOfMemeoryError
原因
当jvm评估需要申请的内存超过jvm堆最大内存时,抛OutOfMemoryError。
解决方法
- 检查程序是否有死循环
- 检查程序是否存在资源未释放
- 检查程序是否瞬间申请大量内存
- 增大堆大小。参数: -Xmx
程序计数器(Program Counter)
记录正在执行的虚拟机字节码指令的地址。每个线程都有自已独立的区域。
虚拟机栈(Java Virtual Machine Statcks)
存储局部变量表(基本数据类型)、操作栈、动态链接、方法出口等信息。
可能抛异常
StockOverflowError、OutOfMemeoryError
原因
- StockOverflowError: 可能是线程请求的栈深度超出虚拟机允许的最大深度。
- OutOfMemeoryError: 可能是多线程环境在创建新线程时申请栈空间时内存不足。
解决方法
对于StockOverflowError异常,需检查程序是否有递归调用次数过多。
对于OutOfMemeoryError 异常,则需要根据系统情况调整参数-Xss参数。
总结公式:
-Xss = (操作系统剩余内存 - (-Xmx) - (-X:MaxPermSize) - 本地方法栈 ) / 预计的线程数
本地方法栈(Native Method Stacks)
C Statck,存储native方法本地变量、操作栈等信息。
可能抛异常
StockOverflowError、OutOfMemeoryError。
原因
*Error:
如果一个线程申请一个很大的本地方法栈时,超过了最大限制则抛*Error。OutOfMemoryError:
如果本地方法栈可以动态扩展,并且本地方法栈申请扩展更多内存,但此时系统内存不足;或者是当在创建一个新的线程时,无法申请到初始化本地方法栈的内存时抛OutOfMemoryError。
解决方法
*Error :控制局部变量数量和大小。
OutOfMemoryError : 增加内存。
参考