2.4 实战:OutOfMemoryError异常

在《Java虚拟机规范》的规定里,除了程序计数器外,虚拟机内存的其他几个运行时区域都有发 生OutOfMemoryError(下文称OOM)异常的可能,本节将通过若干实例来验证异常实际发生的代码 场景(代码清单2-3~2-9),并且将初步介绍若干最基本的与自动内存管理子系统相关的HotSpot虚拟 机参数。

本节实战的目的有两个:第一,通过代码验证《Java虚拟机规范》中描述的各个运行时区域储存 的内容;第二,希望读者在工作中遇到实际的内存溢出异常时,能根据异常的提示信息迅速得知是哪 个区域的内存溢出,知道怎样的代码可能会导致这些区域内存溢出,以及出现这些异常后该如何处 理。

本节代码清单开头都注释了执行时需要设置的虚拟机启动参数(注释中“VM Args”后面跟着的参 数),这些参数对实验的结果有直接影响,请读者调试代码的时候不要忽略掉。如果读者使用控制台 命令来执行程序,那直接跟在Java命令之后书写就可以。如果读者使用Eclipse,则可以参考图2-4在 Debug/Run页签中的设置,其他IDE工具均有类似的设置。

本节所列的代码均由笔者在基于OpenJDK 7中的HotSpot虚拟机上进行过实际测试,如无特殊说 明,对其他OpenJDK版本也应当适用。不过读者需意识到内存溢出异常与虚拟机本身的实现细节密切 相关,并非全是Java语言中约定的公共行为。因此,不同发行商、不同版本的Java虚拟机,其需要的参 数和程序运行的结果都很可能会有所差别。

image-20210915214400673
图2-4 在Eclipse的Debug页签中设置虚拟机参数

本节所列的代码均由笔者在基于OpenJDK 7中的HotSpot虚拟机上进行过实际测试,如无特殊说 明,对其他OpenJDK版本也应当适用。不过读者需意识到内存溢出异常与虚拟机本身的实现细节密切 相关,并非全是Java语言中约定的公共行为。因此,不同发行商、不同版本的Java虚拟机,其需要的参 数和程序运行的结果都很可能会有所差别。