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

(Sun)JVM为什么对内存使用量(-Xmx)有固定的上限?

金承嗣
2023-03-14
问题内容

本着Java的精神:为什么存在MaxPermSize?,我想问一下为什么Sun JVM对其内存分配池的大小使用固定的上限。

默认值为物理RAM的1/4(有上限和下限);结果,如果您有一个内存消耗大的应用程序,则必须手动更改限制(参数-
Xmx),否则您的应用程序将运行不佳,甚至可能因OutOfMemoryError崩溃而崩溃。

为什么这个固定限制甚至存在?为什么JVM不能像大多数操作系统上的本机程序那样按需分配内存?

这将解决Java软件的一类常见问题(只需通过google来查看网上通过设置-Xmx解决问题的提示)。

编辑:

一些答案指出,这将保护系统的其余部分免受Java程序的攻击,从而避免内存泄漏。没有限制,这将耗尽所有内存,从而使整个系统瘫痪。但是,对于任何其他程序,这都是正确的,并且现代OS已经允许您限制程序的最大内存(Linux
ulimit,Windows“作业对象”)。因此,这并不能真正回答以下问题:“为什么JVM与大多数其他程序/运行时环境不同?”。


问题答案:

嗯,到目前为止,我将尝试总结答案。

JVM对其堆大小没有硬性限制是没有技术原因的。它本来可以不用一种语言实现的,实际上许多其他动态语言都没有这种语言。

因此,给JVM一个堆大小限制只是实现者的设计决定。再次猜测为什么这样做有点困难,并且可能没有单一原因。最可能的原因是它有助于通过内存泄漏保护系统免受Java程序的攻击,否则可能会耗尽所有RAM并导致其他应用程序崩溃或系统崩溃。

Sun可以省略该功能,而只是告诉人们使用OS本地资源限制机制,但是他们可能希望始终有一个限制,因此他们自己实现了它。无论如何,JVM需要知道任何此类限制(以适应其GC策略),因此使用OS本地机制将不会节省太多编程工作。

同样,有一个原因为什么这样的内置限制对JVM比不具有GC的“普通”程序(例如C / C ++程序)更为重要:

与具有手动内存管理的程序不同,使用GC的程序即使具有固定的输入数据,也实际上并没有明确定义的内存要求。它仅具有最低要求,即在给定时间点实际存在(可到达)的所有对象的大小之和。但是,实际上,程序将需要额外的内存来保存已失效但尚未GCed的对象,因为GC无法立即收集每个对象,因为这会导致过多的GC开销。因此,GC只会不时启动,因此堆上需要一定的“呼吸空间”,死掉的对象可以等待GC。

这意味着使用GC的程序所需的内存实际上是在节省内存和提高吞吐量(通过让GC减少运行频率)之间的折衷。因此,在某些情况下,将堆限制设置为低于JVM可能使用的限制可能是有意义的,因此以性能为代价来节省RAM。为此,需要一种html" target="_blank">方法来设置堆限制。



 类似资料:
  • 问题内容: 我有一个需要一些内存调整的webapp。尽管我已经对应用程序本身进行了概要分析并进行了精简,但在我们最繁忙的实例上,JVM本身似乎显得过分膨胀。(低容量实例不存在此问题。)详细信息: 平台: RHEL4 64位() Sun Java 6() 带有in的Tomcat 6 我的webapp当前有一些代码在生产中需要运行64位的好处。 我观察到,一段时间(一周)后,JVM的驻留内存大小(如顶

  • JVM选项: 正如预期的那样,JVM将为JVM堆分配将近20MB的内存。 但请参阅以下 GC 详细信息: PSYoungGen总计9216K,已用4612k[0x 00000000 ff 6000000,0x 0000000010000000100000000]< br > Eden空间8192K,56%已用[0x 000000000 ff 600000,0x 0000000 FFA 812d 8

  • 我有一个jar文件,我使用单元文件运行。单元文件中的run命令如下: ExecStart=/usr/bin/java-Xms200m-Xmx465m——启用预览-jar-myapp-1.0.0.jar 我的应用程序总是记录允许使用的最大内存量。它使用以下代码对此进行记录: 由于某种原因, 的值总是比 参数的值小 左右。因此,如果jar文件使用参数运行,则应用程序将仅获得的可用RAM内存。 我的问题

  • 问题内容: 当我使用固定内存进行CUDA数据传输时,我发现数据传输速度大大提高。在linux上,实现此目标的底层系统调用是mlock。从mlock的手册页中可以看出,锁定该页可防止将其换出: mlock()将页面锁定在地址范围内,该地址范围从addr开始并持续len个字节。当调用成功返回时,保证所有包含指定地址范围一部分的页面都驻留在RAM中; 在测试中,我的系统上有几千个可用内存,因此从不存在内

  • 当我运行用pyspark编写的spark作业时,我会运行一个jvm,它的Xmx1g设置似乎无法设置。以下是ps aux的输出: 我的问题是,如何设置此属性?我可以使用SPARK\u DAEMON\u memory和SPARK\u DRIVER\u memory设置主内存,但这不会影响pyspark的派生进程。 我已经尝试了JAVA\u选项,或者实际查看了包的文件,但无法理解这是在哪里设置的。 设置

  • 问题内容: 在过去的一年中,我在应用程序的Java堆使用方面取得了巨大的进步- 减少了66%。为此,我一直在通过SNMP监视各种指标,例如Java堆大小,cpu,Java非堆等。 最近,我一直在监视JVM有多少实际内存(RSS,驻留集),这让我有些惊讶。JVM消耗的实际内存似乎完全独立于我的应用程序堆大小,非堆,eden空间,线程数等。 通过Java SNMP Java堆使用的图形 衡量的堆大小