jvm内存溢出浅析

jvm(oom)(JAVA OutofMemoryError) 类型:
1.Java heap space :
.超出预期的访问量/数据量;
应用系统设计时,一般是有"容量"定义的, 部署这么多机器, 用来处理一定量的数据/业务。
如果访问量突然飙升, 超过预期的阈值, 那么在峰值所在的时间段, 
程序很可能就会卡死、并触发 java.lang.OutOfMemoryError: Java heap space 错误。
.内存泄露(Memory leak):
这也是一种经常出现的情形。由于代码中的某些错误, 导致系统占用的内存越来越多. 
如果某个方法/某段代码存在内存泄漏的, 每执行一次, 就会(有更多的垃圾对象)占用更多的内存.
随着运行时间的推移, 泄漏的对象耗光了堆中的所有内存, 那么 java.lang.OutOfMemoryError: 
Java heap space 错误就爆发了。
2.GC overhead limit exceeded
这种情况发生的原因是, 程序基本上耗尽了所有的可用内存, GC也清理不了。
%98的时间处理,收回的内存不到2%;

JVM抛出 java.lang.OutOfMemoryError: GC overhead limit exceeded 错误就是发出了这样的信号: 
执行垃圾收集的时间比例太大, 有效的运算量太小. 默认情况下, 如果GC花费的时间超过 98%, 
并且GC回收的内存少于 2%, JVM就会抛出这个错误。
 
3.Permgen space:
这些区域的最大值, 由JVM启动参数 -Xmx 和 -XX:MaxPermSize 指定. 如果没有明确指定, 则根据操作系统平台和物理内存的大小来确定。
java.lang.OutOfMemoryError: PermGen space 错误信息所表达的意思是: 永久代(Permanent Generation) 内存区域已满
原因分析
在JDK1.7及之前的版本, 永久代(permanent generation) 主要用于存储加载/缓存到内存中的 class 定义, 包括 class 的 名称(name), 字段(fields), 方法(methods)
和字节码(method bytecode); 以及常量池(constant pool information); 
对象数组(object arrays)/类型数组(type arrays)所关联的 class, 还有 JIT 编译器优化后的class信息等。
很容易看出, PermGen 的使用量和JVM加载到内存中的 class 数量/大小有关。
可以说 java.lang.OutOfMemoryError: PermGen space 的主要原因, 是加载到内存中的 class 数量太多或体积太大。
 
4.Metaspace
Java8及以上】这些内存池的最大值, 由 -Xmx 和 -XX:MaxMetaspaceSize 等JVM启动参数指定. 如果没有明确指定, 则根据平台类型(OS版本+JVM版本)和物理内存的大小来确定。
java.lang.OutOfMemoryError: Metaspace 错误所表达的信息是: 元数据区(Metaspace) 已被用满
从Java 8开始,内存结构发生重大改变, 不再使用Permgen, 而是引入一个新的空间: Metaspace. 这种改变基于多方面的考虑, 部分原因列举如下:
Permgen空间的具体多大很难预测。指定小了会造成 java.lang.OutOfMemoryError: Permgen size 错误, 设置多了又造成浪费。
为了 GC 性能 的提升, 使得垃圾收集过程中的并发阶段不再 停顿, 另外对 metadata 进行特定的遍历(specific iterators)。
对 G1垃圾收集器 的并发 class unloading 进行深度优化。
在Java8中,将之前 PermGen 中的所有内容, 都移到了 Metaspace 空间。例如: class 名称, 字段, 方法, 字节码, 常量池, JIT优化代码, 等等。
Metaspace 的使用量与JVM加载到内存中的 class 数量/大小有关。可以说, java.lang.OutOfMemoryError: Metaspace 错误的主要原因, 是加载到内存中的 class 数量太多或者体积太大

猜你喜欢

转载自blog.csdn.net/qq_15140841/article/details/79768431