19

我一直想知道,为什么 Java 需要你手动设置堆大小?我的印象是,用其他语言编写的程序只会根据程序运行的需要分配尽可能多的内存,直到操作系统无法再分配。

在 Java 世界中,我们需要设置堆、堆栈和 permgen 大小。虽然这很简单,但忘记将这些增加到“足够大”的数字是我看到服务器宕机的第一大原因。

为什么不能告诉 Java 随着时间的推移尽可能多地增长堆/堆栈/permgen?

4

4 回答 4

8

三个原因:

  1. 因为 Java 旨在成为一种用于编写 Web 应用程序的语言。通常认为让 Web 应用程序接管所有机器资源并不是一个好主意。
  2. 因为Java是垃圾收集的。除了指定内存上限外,堆大小也会触发垃圾收集。本质上,您是在说“您可以使用这么多,但是当您达到该限制时,您必须进行整理”。
  3. 有许多类的应用程序确实希望限制 Java 进程使用的内存量,例如,当两个进程都没有足够的内存时,其他进程继续运行更为重要。
  4. 因为能够限制堆大小是一个特性。如果您喜欢进程可以拥有无​​限内存的方法(如提到的其他语言),那么您总是可以将堆限制设置为超过它可能获得的。如果你想限制堆大小,你可以这样做。其他语言只有其中一种可能的行为,从而降低了它们的灵活性。
于 2010-08-18T21:42:02.407 回答
6

我的解释是 Sun 是一家专注于销售 Big Box 的公司,他们喜欢系统管理员可以在这些盒子上做事。运行一个系统来填满所有内存是一个很好的方法来运行它并且不能有效地采取行动来恢复操作,因为你不能分配内存来创建一个登录 shell。

于 2010-08-18T21:08:49.893 回答
4

我认为因为计算机的实际内存是有限的。因此,从某种意义上说,JVM 允许您在所有内存被浪费之前检测到 memleaks。
另外,如果您在同一台机器上运行多个 JVM 该怎么办——在这种情况下,您如何允许每个 JVM “按需增长”?

于 2010-08-18T21:08:16.380 回答
1

因为动态地增加堆、堆栈和 permgen 大小只会使服务器停止运行。在这样的世界中,服务器最终会泄露其所有资源。

此外,开发自动内存管理并不像今天这样成熟。如果您选择错误的默认值,拥有虚拟限制会使事情变得更容易,但它会使后端的编码效率降低一些。

是的,这些都是猜测,但都是合理的;尤其是当您考虑 Java 的 / Oak 的嵌入式机顶盒编程起源时。嵌入式系统不会有交换或磁盘支持的虚拟内存,那么为什么要让 JVM 表现得好像它是可用的一样呢?

于 2010-08-18T21:14:15.547 回答