Java JVM能否自动使用更多交换空间来防止内存不足错误

Java JVM能否自动使用更多交换空间来防止内存不足错误,java,jvm,heap-memory,virtual-memory,Java,Jvm,Heap Memory,Virtual Memory,如中所述,当分配堆空间时,JVM不区分物理内存和虚拟内存。当java对象和计算的内存分配开始时,JVM开始区分虚拟内存和物理内存。如果有足够的交换空间(在Linux机器上),为什么会发生内存不足错误?JVM不应该简单地使用交换空间来完成计算,尽管速度很慢 例如:RAM:14GB,交换空间:10GB 如果java应用程序需要20GB的空间,它不能利用交换空间(虚拟内存)并完成应用程序的运行吗 对于java应用程序,堆空间和虚拟内存之间的相互作用是什么?进程从不知道它们使用的内存的哪些部分在虚拟内存

如中所述,当分配堆空间时,JVM不区分物理内存和虚拟内存。当java对象和计算的内存分配开始时,JVM开始区分虚拟内存和物理内存。如果有足够的交换空间(在Linux机器上),为什么会发生内存不足错误?JVM不应该简单地使用交换空间来完成计算,尽管速度很慢

例如:RAM:14GB,交换空间:10GB

如果java应用程序需要20GB的空间,它不能利用交换空间(虚拟内存)并完成应用程序的运行吗


对于java应用程序,堆空间和虚拟内存之间的相互作用是什么?

进程从不知道它们使用的内存的哪些部分在虚拟内存中,哪些部分在物理内存中

这是由操作系统以透明的方式管理的。通常,最常用或最近使用的内存“块”(正确的术语是“页”)保存在物理内存中。一个程序只需要内存,操作系统分配内存并决定每个页面的位置(虚拟或物理)

要使用某个内存块,您必须拥有该内存块所在的页面。将一页内存从虚拟移动到物理是非常昂贵的,因此必须尽量避免。因此,您通常指定堆小于物理内存,以允许操作系统尝试将其全部保留在物理内存中(请注意,您应该为操作系统和其他应用程序留出额外的物理内存)

至于问题:

它不能利用额外的8GB交换空间(虚拟内存)并完成应用程序的运行吗

您已经告诉JVM最多使用12GB内存,现在您想让JVM忽略您的命令并扩展到12GB之外吗?JVM是一个好人,它服从您,您应该自己决定是选择内存限制来确保良好的性能,还是不选择堆限制和风险分页(当然,即使没有明确的限制,也会受到主机操作系统和资源的限制)

JVM不应该简单地使用交换空间来完成计算,尽管速度很慢

这不仅是缓慢的,如果你有旋转磁盘,它可以慢50000x以上。执行GC时,它可以扫描GB/s的对象,但想象一下,它每秒只能扫描100个对象。这意味着它不再需要几秒钟,而是需要大约一天的时间。注意:发生这种情况时,机器将无法使用。在Windows上,您甚至不能停止进程,而必须关闭它以使其停止

如果我不提供任何-Xmx参数并让java应用程序运行所需的时间,我能测试这个吗

解包只不过是主内存。即使您将最大堆大小设置为大于主内存,也不意味着它将使用那么多,您还必须设置最小值


这可能是一个有趣的测试,看看您的进程是否成功完成,不管时间长短,但我希望它需要更长的时间。

我认为JVM限制了允许的内存使用,不是因为它没有足够的内存,而是因为应用程序跨越了它的界限,我不知道你读了彼得·劳瑞对你所联系的问题的回答了吗?他回答了你的大部分问题,如果不是全部的话。是的,我回答了。但我不明白为什么java进程在有足够的虚拟内存可供使用时会给出OOM。你的问题毫无意义。如果指定选项
-Xmx12g
,则告诉JVM不要使用超过12GiB的内存,无论它是物理RAM还是交换空间。为什么您希望JVM抵制您的命令?也许我应该从示例中删除这一行。这可能会分散人们对实际问题的注意力。我只对以下几点感兴趣:如果java应用程序需要比物理内存更多的空间,但比物理+虚拟内存的组合更少的空间,那么它是否可以在不提供OOM的情况下完成?如果是,我怎样才能做到这一点?我知道java应用程序不知道分配的内存位置在哪里。谢谢。如何向jvm指定以下内容:“使用尽可能多的堆空间,以及虚拟内存来完成应用程序的运行”——我不介意是否涉及分页。目标是完成应用程序的运行,而不必担心所花费的时间。本文的示例中提到了应用程序/RAM统计信息。从我提供的链接:
如果您没有设置初始或最大堆大小,GC将根据需要扩展和收缩堆。但是,如果通过使用-Xms和-Xmx选项修复堆大小,GC不会扩展或收缩Java™ 堆
。同样,进程只要求内存,由操作系统决定在何处分配内存。假设Oracle Java SDK也是如此,那么以下是否正确:a)如果未提供-Xms和-Xmx选项,假设没有默认值,并且b)如果有足够的交换空间,并且java应用程序需要的空间超过可用的物理内存,则不会出现OOM错误?@Raghava您现在不必提供-Xmx,它默认为主内存的1/4。谢谢。如果java应用程序需要比可用物理内存更多的空间,我对测试它需要多长时间感兴趣。如果我不提供任何-Xmx参数,让java应用程序运行所需的时间(并希望它使用虚拟内存),我是否能够测试这一点?谢谢。我将使用-Xmx选项测试它,并且不指定任何堆大小。