一:GC overhead limit exceeded
数据量过大:当应用程序处理大量的数据时,会占用大量的内存和计算资源。如果内存资源不足,则可能会在垃圾回收过程中出现 GC overhead limit exceeded 错误
程序代码有问题:如果 应用程序的代码有问题,比如内存泄漏、无限递归等,就有可能在垃圾回收过程中出现 GC overhead limit exceeded 错误。
使用了过多的Java对象:如果应用程序创建了大量的Java对象,这些对象占用大量的内存资源,可能会导致垃圾回收机制频繁执行,从而出现 GC overhead limit exceeded 错误。
【出现报错:dump文件通过工具[MemoryAnalyzer]解析后指向递归的代码处】
经常性报错又不能急时dump的话,就在配置文件增加如下配置来获得日志文件:
#宕机日志记录
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/home/tomcat/logs
为了避免出现GC overhead limit exceeded错误,可以采取以下措施:
1.增加系统资源:可以增加集群的资源,例如增加计算节点、提高每个节点的内存大小。
2.优化程序代码:可以对程序代码进行优化,避免出现内存泄漏、无限递归等问题,减少程序创建过多的Java对象。
3.增加垃圾回收机制的参数:可以通过修改JVM参数来调整垃圾回收机制的策略和时间
参数详解:
-Xss:规定了每个线程虚拟机栈及堆栈的大小,此配置将会影响此进程中并发线程数的大小
-Xms:表示初始化JAVA堆的大小及该进程刚创建出来的时候,他的专属JAVA堆的大小,一旦对象容量超过了JAVA堆的初始容量,JAVA堆将会自动扩容到-Xmx大小。
-Xmx:表示java堆可以扩展到的最大值,在很多情况下,通常将-Xms和-Xmx设置成一样的,因为当堆不够用而发生扩容时,会发生内存抖动影响程序运行时的稳定性。
二:java.lang.OutOfMemoryError: Metaspace
初始设置元空间:
"-XX:MetaspaceSize=64m"
"-XX:MaxMetaspaceSize=128m"
监控元空间运行状况:
jstat -gc 28481 5000 5
发现元空间 MU:120.92Mb,后面运行没过多久就报错:java.lang.OutOfMemoryError: Metaspace
改为
"-XX:MetaspaceSize=256m"
"-XX:MaxMetaspaceSize=256m"
建议将
MetaspaceSize
和MaxMetaspaceSize
设置为同样大小,避免频繁扩容
MetaspaceSize容量设置的过大,导致Meta区使用率太低,浪费了比较多的堆内存
后面改为MetaspaceSize:256M继续监控
建议设置元空间值, 如果不设置会怎么样?
不设置元空间默认就是21M, 很容易就会放满, 通常我们的war可能都是几十M, 甚至几个G. 如果我们在启动程序的时候, 会启动几分钟. 这很有可能是没有设置元空间的大小.
放满后会发生full GC, 然后在扩大一点元空间, 扩大到25M, 重新开始, 过了一会又放满了, 再次full GC[并会卸载没有用的类], 在扩大一点, 元空间扩大到30M, 就这样一直发生full GC, 然后一直扩大元空间, 直到扩大的元空间大小合适, 不再发生full gc, 程序才会正常启动运行. 这是个很耗时耗性能的操作, 这样的full GC也是没有必要的.
如果项目启动较慢,多次重复启动,考虑是不是元空间设置不合理,或者内存不够导致
如果不指定元空间的大小,默认情况下,元空间最大的大小是系统内存的大小,元空间一直扩大,虚拟机可能会消耗完所有的可用系统内存
元空间( Meta Space)存储什么?
用于存储已被虚拟机加载的类信息
、常量
、静态变量
,即时编译器编译后的代码缓存等