简体   繁体   English

为什么需要指定 Java 堆大小?

[英]Why do you need to specify the Java heap size?

I have always wondered, why does Java require you set the heap size manually?我一直很纳闷,为什么Java需要你手动设置堆大小呢? I was under the impression that programs written in other languages would just allocate as much memory as needed as the program run until the OS could allocate no more.我的印象是,用其他语言编写的程序只会在程序运行时根据需要分配尽可能多的 memory,直到操作系统无法再分配为止。

In the Java world we need to set the heap, stack, and permgen size.在 Java 世界中,我们需要设置堆、栈和 permgen 大小。 While this is simple enough forgetting to increase these to "large enough" numbers is the #1 reason I have seen servers go down.虽然这很简单,但忘记将这些增加到“足够大”的数字是我看到服务器 go 宕机的主要原因。

Why is it not possible to tell Java to grow the heap/stack/permgen as much as it needs over time?为什么不能告诉 Java 随着时间的推移尽可能多地增加堆/堆栈/permgen?

Three reasons: 三个原因:

  1. Because Java was intended to be a language for writing web apps. 因为Java旨在成为编写Web应用程序的语言。 It is generally not thought to be a good idea to let a web app take over all of the machine resources. 通常不认为让Web应用程序接管所有机器资源是个好主意。
  2. Because Java is garbage collected. 因为Java是垃圾收集的。 As well as specifying an upper limit of memory, the heap size triggers garbage collection too. 除了指定内存的上限外,堆大小也会触发垃圾回收。 Essentially you are saying "you can use this much, but when you hit that limit you've got to tidy up". 从本质上讲,你说的是“你可以使用这么多,但是当你达到这个极限时,你必须整理一下”。
  3. There are many classes of applications where you do want to limit the amount of memory used by the Java process, eg where it is more important that other processes continue when there is insufficient memory for both. 有许多类应用程序,您确实希望限制Java进程使用的内存量,例如,当两者的内存不足时,其他进程继续运行更为重要。
  4. Because being able to limit heap size is a feature . 因为能够限制堆大小是一个功能 If you like the approach where the process can have unlimited memory, (as on the other languages mentioned) then you can always set the heap limit to be more than it could possibly acquire. 如果您喜欢该进程可以拥有无​​限内存的方法(与所提到的其他语言一样),那么您始终可以将堆限制设置为超出其可能获取的范围。 If you want to limit heap size, you can do that. 如果要限制堆大小,可以这样做。 Other languages have only one of those possible behaviours, making them less flexible. 其他语言只有其中一种可能的行为,使它们不那么灵活。

My interpretation is that Sun is a company focused on selling Big Boxes and they like that the sysadmins can do things on these boxes. 我的解释是,Sun是一家专注于销售Big Boxes的公司,他们喜欢系统管理员可以在这些盒子上做事。 Running a system to fill all the memory is a good way to run it into the ground and be unable to efficiently take action to restore operation because you cannot allocate memory to create a login shell for example. 运行系统来填充所有内存是将其运行到地面并且无法有效采取操作来恢复操作的好方法,因为您无法分配内存来创建登录shell。

I think because actual memory of computer is finite. 我认为因为计算机的实际记忆是有限的。 So, in a sense, JVM allows you to detect memleaks before all memory is wasted. 因此,从某种意义上说,JVM允许您在浪费所有内存之前检测memleaks。
Plus, what to do if you run several JVMs on the same machine -- in this case how do you allow each of these JVM to grow "as much as it needs"? 另外,如果您在同一台机器上运行多个JVM,该怎么办 - 在这种情况下,您如何允许这些JVM中的每一个“尽可能多地”增长?

Because growing the heap, stack, and permgen size dynamically just would make the server go down anyway. 因为动态地增加堆,堆栈和permgen大小只会使服务器失败。 In such a world, the server would eventually leak away all of its resources. 在这样的世界中,服务器最终会泄漏其所有资源。

Also, developing automatic memory management wasn't as mature as it is today. 此外,开发自动内存管理并不像现在这样成熟。 Having virtual limits makes things easier if you pick the wrong defaults, but it can make the coding a bit less efficient on the back end. 如果选择了错误的默认值,则具有虚拟限制会使事情变得更容易,但它会使编码在后端的效率降低。

Yes, these are guesses, but reasonable ones; 是的,这些是猜测,但是合理的; especially when you consider Java's / Oak's origins of embedded set top box programming. 特别是当你考虑Java / Oak的嵌入式机顶盒编程的起源时。 It isn't like an embedded system is going to have swap or disk backed virtual memory, so why make the JVM act as if it were available? 它不像嵌入式系统会有交换或磁盘支持的虚拟内存,那么为什么让JVM表现得像是可用的呢?

Old topic but I got here and I think I know the answer.老话题,但我到了这里,我想我知道答案了。

Complementing what Peter said, the Java ecosystem is entirely designed for system administrators and support teams.作为 Peter 所说的补充,Java 生态系统完全是为系统管理员和支持团队设计的。 In the same way that the administrator defines the memory resources that he wants to be used by the application, the same happens with database connections (JNDI) in which you do not need to give the application or your developer where the database production is, just the name that references the resource.就像管理员定义他希望应用程序使用的 memory 资源一样,数据库连接 (JNDI) 也是如此,您不需要向应用程序或您的开发人员提供数据库生产位置,只需引用资源的名称。 Everything Sun did had a perfect mission-critical management system. Sun 所做的一切都有一个完善的关键任务管理系统。 In the case of the Solaris operating system, Sun has developed a feature called "projects" ( https://docs.oracle.com/cd/E37838_01/html/E61042/index.html ) that serves for the administrator to limit server resources in applications of any programming language (as you mentioned above).对于 Solaris 操作系统,Sun 开发了一个称为“项目”的功能 ( https://docs.oracle.com/cd/E37838_01/html/E61042/index.html ),供管理员限制服务器资源在任何编程语言的应用程序中(如上所述)。 Therefore, it is important for a production system to let the system administrator know how much resources the application is able to use and to be able to limit what is necessary.因此,对于生产系统来说,让系统管理员知道应用程序能够使用多少资源并能够限制必要的资源是很重要的。 And this is not unique to Java or Sun products.这并不是 Java 或 Sun 产品所独有的。 In the case of .NET it is possible to limit these resources ( https://learn.microsoft.com/en-us/iis/configuration/system.applicationhost/applicationpools/add/processmodel ), Ruby ( https://gist.github . com/jjb/7389552), Node.JS ( How do I determine the correct "max-old-space-size" for node.js? ) and etc.在 .NET 的情况下,可以限制这些资源 ( https://learn.microsoft.com/en-us/iis/configuration/system.applicationhost/applicationpools/add/processmodel ),Ruby ( https://gist. github . com/jjb/7389552)、Node.JS( 如何确定 node.js 的正确“最大旧空间大小”? )等。

Learning to manage is important like learning to develop.学习管理与学习发展一样重要。 A lot of people think Docker is a modern marvel while FreeBSD Jails, Solaris Zones and so on existed a long time ago.许多人认为 Docker 是一个现代奇迹,而 FreeBSD Jails、Solaris Zones 等早已存在。 What makes good software not fail is that it is well written and well managed.好的软件不会失败的原因是它写得好,管理得好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM