Java之内存溢出
Java之内存溢出 | OutOfMemoryError
我们都知道,在Java的世界里,由JVM管理着Java中的“垃圾对象”,也就是不被引用的对象;当一个对象不被其它对象引用的时候,该对象就会被垃圾回收器清理掉。但是在某些情况下,如果我们的代码导致垃圾回收器无法清理掉多余的对象,那么程序就会爆OurOfMemoryError(OOM),下面用一段代码来触发下该异常。
import java.util.ArrayList;
import java.util.List;public class E {public static void main(String[] args) {List<String> list = new ArrayList<>();while (true) {list.add("Hello");}}
}
这段代码被执行之后,控制台不会有任何输出,稍等一会儿后,控制台就会报内存溢出错误,效果如下:
解决方案
调整内存大小是一个后手,在这之前,程序员应该尽量优化数据结构,降低内存溢出出现的频率,如果这时候还存在内存溢出的情况,再去考虑调整内存大小。
我们可以在启动项目的时候使用-Xms
、-Xmx
两个参数规定Java的标准内存空间与最大内存空间。示例命令如下:
java -Xms512m -Xmx2g YourProgram
请注意:标准内存空间与最大内存空间不要超过计算机或服务器的运行空间,并应当给其它程序保留一定的运算空间,否则你的计算机可能会出现卡死无法执行的情况。
内存监控
除了优化数据结构、增加运行空间之外,我们还可以在启动项目的时候添加-Xloggc:<path>
参数,当程序发生内存泄露的时候,系统会生成当前的内存快照,并保存在<path>
下,下面是示例命令与生成的文件内容:
java -Xloggc:gc.log YourProgram
执行上面命令后,当项目出现内存溢出时,就会将当前的内存快照保存在./gc.log
下,此时查看./gc.log
,内容如下:
OpenJDK 64-Bit Server VM (25.422-b05) for linux-amd64 JRE (1.8.0_422-8u422-b05-1~22.04-b05), built on Jul 21 2024 21:59:18 by "buildd" with gcc 11.4.0
Memory: 4k page, physical 1731168k(298728k free), swap 0k(0k free)
CommandLine flags: -XX:InitialHeapSize=27698688 -XX:MaxHeapSize=443179008 -XX:+PrintGC -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops
0.062: [GC (Allocation Failure) 6771K->2386K(27776K), 0.0047142 secs]
0.069: [GC (Allocation Failure) 5551K->5545K(27776K), 0.0097146 secs]
0.081: [GC (Allocation Failure) 10293K->10293K(27776K), 0.0176603 secs]
0.104: [GC (Allocation Failure) 17415K->17415K(27776K), 0.0304972 secs]
0.135: [Full GC (Allocation Failure) 17415K->7390K(27776K), 0.0090143 secs]
0.150: [GC (Allocation Failure) 18073K->18073K(27776K), 0.0044526 secs]
0.154: [Full GC (Allocation Failure) 18073K->10951K(27776K), 0.0183721 secs]
0.186: [GC (Allocation Failure) 26976K->26976K(43804K), 0.0052467 secs]
0.191: [Full GC (Allocation Failure) 26976K->16293K(43804K), 0.0167542 secs]
0.227: [GC (Allocation Failure) 40329K->40329K(75076K), 0.0088539 secs]
0.236: [Full GC (Allocation Failure) 40329K->24305K(75076K), 0.0247799 secs]
0.289: [GC (Allocation Failure) 60360K->60360K(121948K), 0.0129599 secs]
0.302: [Full GC (Allocation Failure) 60360K->36323K(121948K), 0.0361519 secs]
0.383: [GC (Allocation Failure) 90406K->90406K(138204K), 0.0188256 secs]
0.402: [Full GC (Allocation Failure) 90406K->54351K(138204K), 0.0663107 secs]
0.529: [GC (Allocation Failure) 135475K->135475K(219328K), 0.0272062 secs]
0.556: [Full GC (Allocation Failure) 135475K->81392K(219328K), 0.0796819 secs]
0.734: [GC (Allocation Failure) 203078K->203078K(368960K), 0.0522887 secs]
0.786: [Full GC (Allocation Failure) 203078K->121954K(368960K), 0.1163572 secs]
0.903: [Full GC (Allocation Failure) 121954K->121942K(419712K), 0.1044216 secs]
至于如何分析该内容,那不是本章节的重点,就不赘述咯,这里只是提供一个思路。