当前位置: 首页 > 面试题库 >

即使没有内存,我也会遇到java.lang.OutOfMemoryError吗?

公羊英达
2023-03-14
问题内容

我正在阅读揭露java.lang.Out OfMemoryError,我想知道我是否正确理解它。的确,如果Java VM抛出

java.lang.OutOfMemoryError:请求的阵列大小超出VM限制

这意味着VM拒绝了数组的创建,因为它已经超出了预定义的限制(超出了VM的限制),而 不是 因为我的堆空间用完了吗?

我是否可以说这java.lang.OutOfMemoryError: Requested array size exceeds VM limit并不表示记忆不足?

即使我有 无限的 记忆 无处不在 ,Java虚拟机仍然可以抛出java.lang.OutOfMemoryError: Requested array size exceeds VM limit,如果它不喜欢我的请求创建数组 ñ 大小?


问题答案:

带有HotSpot VM的Java SE
6
报价故障排除指南

3.1.3详细信息:(行Requested array size exceeds VM limit内粗体为我的):

详细消息Requested array size exceeds VM limit表明应用程序(或该应用程序使用的API)尝试分配大于堆大小的数组。例如,如果应用程序尝试分配512MB的数组,但最大堆大小为256MB,OutOfMemoryError则将抛出原因Requested array size exceeds VM limit。在大多数情况下,问题可能是 配置问题 (堆大小太小),或者
是导致应用程序尝试创建大数组的错误 ,例如,当使用计算算法来计算数组中的元素数时尺寸不正确。

更新:在 @Pacerier的 鼓励下,我进行了一些快速测试。我编写了一个示例程序:

public class VmLimitTest {

    public static final int SIZE = 2;

    public static void main(String[] args) throws InterruptedException {
        while(true) {
            byte[] a = new byte[SIZE * 1024 * 1024];
            TimeUnit.MILLISECONDS.sleep(10);
        }
    }
}

并使用以下JVM选项运行它:

-Xms192m -Xmx192m -XX:NewRatio=2 -XX:SurvivorRatio=6 -XX:+PrintGCDetails

这是他们的意思:

  • 整个堆为192 MiB(-Xms192m -Xmx192m
  • 年轻一代(eden +幸存者)空间为64 MiB,老一代为128 MiB(-XX:NewRatio=2
  • 每个幸存者空间(两个)为8 MiB,因此伊甸园剩下48 MiB(比率为1:6 -XX:SurvivorRatio=6

在测试时,我发现了以下内容:

  • 如果新创建的数组可以放入eden(小于48 MiB),则程序运行正常
  • 令人惊讶的是,当数组大小超过eden大小,但可以放入eden和 一个 幸存者空间(介于48和56 MiB之间)时,JVM可以在eden和Survivor上分配单个对象(重叠两个区域)。整齐!
  • 一旦阵列大小超过eden +单个幸存者(高于56 MiB),新创建的对象将绕过eden和幸存者空间而直接放置在旧世代中。这也意味着突然之间一直在执行完整的GC-非常糟糕!
  • 我可以轻松分配127 MiB的数据,但是尝试分配129 MiB 会抛出 异常 OutOfMemoryError: Java heap space

这是底线-您不能创建尺寸大于上一代的对象。尝试这样做将导致OutOfMemoryError: Java heap space错误。那么,我们Requested array size exceeds VM limit什么时候可以期望可怕呢?

我尝试使用更大的对象运行同一程序。达到阵列长度限制后,我切换到long[]了该端口,可以轻松达到7 GiB。使用128
MiB的最大堆声明了JVM仍在抛出OutOfMemoryError: Java heap space(!),我设法触发OutOfMemoryError: Requested array size exceeds VM limit错误,试图在单个对象中分配8 GiB。我在具有3 GiB物理内存和1 GiB交换的32位Linux计算机上对此进行了测试。

话虽这么说,您可能永远都不会遇到此错误。该文档似乎不准确/已过时,但确实有一个结论: 这可能是一个错误, 因为创建如此大的数组非常罕见。



 类似资料:
  • 问题内容: 我正在尝试将2.5GB的txt文件读入我的应用程序。我正在运行Win7 x64,并且有43GB的可用内存(64GB中的可用空间)。我尝试使用-Xmx -XX:MaxParmSize -XX:ParmSize等。这些都不影响错误。我还能尝试什么?因为我当然有足够的可用堆空间,所以这个错误似乎很奇怪。 我在跑步 非常感谢。 =============答案============== 好,我

  • 我已经删除了所有Azure虚拟机,现在我正在尝试从经典存储帐户中删除vhds容器存储blob。它给了我这个错误: Blob上当前有一个租约,请求中没有指定租约ID 我发现一篇文章提到了这个错误:https://blogs.technet.microsoft.com/thbrown/2015/04/04/there-is-currently-a-lease-on-the-blob-and-no-le

  • 问题内容: 喜欢读一些答案后,这个和JEP-346,我已经意识到,G1确实释放内存返回给操作系统。 但是,它是否将内存释放回操作系统,甚至达到当前内存使用可能降至初始堆内存以下的程度(即在此JEP之前,在我的情况下为JDK11)? 假设我有一个运行在RAM 上并设置为的Java 11 VM ,但是我只消耗了。G1是否将足够的内存释放回操作系统? 我在任何地方都找不到任何文件说G1被限制在发布时要牢

  • 我使用CORS请求将数据发布到不同域上的php脚本。我收到错误: 跨域请求被阻止:同源策略不允许读取“mydomain”处的远程资源(原因:缺少CORS标头“Access-Control-Allow-Origin”)。 我已经使用以下代码在php中设置了标题。 我也在这篇文章中尝试了这个代码 这是供参考的javascript代码 响应标题 请求标头 但我运气不好任何帮助我都很感激

  • 我使用的是Spring-data-redis cache(1.6.1),Jredis Client2.7.3。我们希望启用故障转移。如果redis服务器停机,我希望应用程序继续工作 1)如果我使用spring-data xml配置,redis cache工作良好。它调用后端,缓存数据,然后在第二次调用时不调用后端。但是,我不知道如何捕获redis异常,如果服务器使用xml配置关闭,并返回null,

  • 问题内容: 我正在使用IText库来促进applet中的pdf导出。在导出调用期间,它失败并显示以下错误: 我在JD Decompiler中打开了Itext jar / PdfPtable.class,并确认该类具有completeRow作为公共方法。 即使在jar / class拥有a的情况下,有人可以解释抛出a的可能情况吗? 这是堆栈跟踪;可能不是很有帮助,因为大多数调用是针对我们的应用程序的