(Oracle)JVM为什么对内存使用量(-Xmx)有固定的上限? [英] Why does the (Oracle) JVM have a fixed upper limit for memory usage (-Xmx)?

查看:98
本文介绍了(Oracle)JVM为什么对内存使用量(-Xmx)有固定的上限?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

本着问题的精神 Java:为什么存在MaxPermSize?,我是d想问为什么Oracle JVM对其内存分配池的大小使用固定的上限.

In the spirit of question Java: Why does MaxPermSize exist?, I'd like to ask why the Oracle JVM uses a fixed upper limit for the size of its memory allocation pool.

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

The default is 1/4 of your physical RAM (with upper & lower limit); as a consequence, if you have a memory-hungry application you have to manually change the limit (parameter -Xmx), or your app will perform poorly, possible even crash with an OutOfMemoryError.

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

Why does this fixed limit even exist? Why does the JVM not allocate memory as needed, like native programs do on most operating systems?

这将解决Java软件的一类常见问题(只需Google即可查看网上有多少通过设置-Xmx来解决问题的提示).

This would solve a whole class of common problems with Java software (just Google to see how many hints there are on the net on solving problems by setting -Xmx).

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

Some answers point out that this will protect the rest of the system from a Java program with a run-away memory leak; without the limit this would bring the whole system down by exhausting all memory. This is true. However, it is equally true for any other program, and modern OSes already let you limit the maximum memory for a programm (Linux ulimit, Windows "Job Objects"). So this does not really answer the question, which is "Why does the JVM do it differently from most other programs / runtime environments?".

推荐答案

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

Hm, I'll try summarizing the answers so far.

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

There is no technical reason why the JVM needs to have a hard limit for its heap size. It could have been implemented without one, and in fact many other dynamic languages do not have this.

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

Therefore, giving the JVM a heap size limit was simply a design decision by the implementors. Second-guessing why this was done is a bit difficult, and there may not be a single reason. The most likely reason is that it helps protect a system from a Java program with a memory leak, which might otherwise exhaust all RAM and cause other apps to crash or the system to thrash.

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

Sun could have omitted the feature and simply told people to use the OS-native resource limiting mechanisms, but they probably wanted to always have a limit, so they implemented it themselves. At any rate, the JVM needs to be aware of any such limit (to adapt its GC strategy), so using an OS-native mechanism would not have saved much programming effort.

还有一个原因,为什么这种内置限制对JVM比没有GC的普通"程序(例如C/C ++程序)更为重要:

Also, there is one reason why such a built-in limit is more important for the JVM than for a "normal" program without GC (such as a C/C++ program):

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

Unlike a program with manual memory management, a program using GC does not really have a well-defined memory requirement, even with fixed input data. It only has a minimum requirement, i.e. the sum of the sizes of all objects that are actually live (reachable) at a given point in time. However, in practice a program will need additional memory to hold dead, but not yet GCed objects, because the GC cannot collect every object right away, as that would cause too much GC overhead. So GC only kicks in from time to time, and therefore some "breathing room" is required on the heap, where dead objects can await the GC.

这意味着使用GC的程序所需的内存实际上是在节省内存和提高吞吐量(通过让GC减少运行频率)之间的折衷.因此,在某些情况下,将堆限制设置为低于JVM可能使用的限制是有意义的,因此可以节省RAM,但会牺牲性能.为此,必须有一种设置堆限制的方法.

This means that the memory required for a program using GC is really a compromise between saving memory and having good througput (by letting the GC run less often). So in some cases it may make sense to set the heap limit lower than what the JVM would use if it could, so save RAM at the expense of performance. To do this, there needs to be a way to set a heap limit.

这篇关于(Oracle)JVM为什么对内存使用量(-Xmx)有固定的上限?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆