为什么Java堆的最大大小是固定的? [英] Why is the maximum size of the Java heap fixed?

查看:135
本文介绍了为什么Java堆的最大大小是固定的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能,以便在VM启动后增加Java堆的最大大小。这是什么技术原因?垃圾收集算法是否依赖于具有固定数量的内存来处理?或者是出于安全原因,通过消耗所有可用内存来阻止Java应用程序DOS系统上其他应用程序的DOS应用程序?

解决方案

<在Sun的JVM中,最后我知道,整个堆必须分配在连续的地址空间中。我认为,对于大堆值,在启动后添加到地址空间非常困难,同时确保它保持连续。你可能需要在启动时获得它,或者根本不需要。因此,它是固定的。

即使没有立即使用它,整个堆的地址空间也会在启动时保留。如果它不能为您传递的-Xmx的值保留足够大的连续地址空间块,则它将无法启动。这就是为什么在32位Windows上分配大于1.4GB的堆是很困难的 - 因为很难找到这种大小或更大的连续地址空间,因为某些DLL喜欢在某些地方加载,分割地址空间。由于地址空间非常多,因此这并不是一个真正的问题。



这几乎肯定是出于性能原因。我找不到一个了不起的链接详细说明这一点,但这是一个来自彼得凯斯勒(完整链接 - 一定要阅读评论),我发现时搜索。我相信他在Sun的JVM上工作。


我们需要连续内存
区域作为堆的原因是我们有一批
的边数据结构,它们是
的索引,由堆的
起始处的(缩放)偏移索引。例如,我们用
卡片标记数组对
跟踪对象引用进行更新,每个512字节的堆有一个字节
。当我们
在堆中存储一个引用时,我们有
来标记
卡标记数组中的相应字节。我们右移商店的
目的地地址,
使用它来索引卡片标记数组。
有趣的寻址算术游戏you
在Java中无法做到,您可以在C ++中玩(
to :-)

这是在2004年 - 我不确定自那时以来发生了什么变化,但我确信它仍然成立。如果使用像Process Explorer这样的工具,则可以看到Java应用程序的虚拟大小(添加虚拟大小和专用大小内存列)包括从启动点起的总堆大小(加上其他所需空间,无疑) ,即使进程所使用的内存不存在,直到堆开始填满......


It is not possible to increase the maximum size of Java's heap after the VM has started. What are the technical reasons for this? Do the garbage collection algorithms depend on having a fixed amount of memory to work with? Or is it for security reasons, to prevent a Java application from DOS'ing other applications on the system by consuming all available memory?

解决方案

In Sun's JVM, last I knew, the entire heap must be allocated in a contiguous address space. I imagine that for large heap values, it's pretty hard to add to your address space after startup while ensuring it stays contiguous. You probably need to get it at startup, or not at all. Thus, it is fixed.

Even if it isn't all used immediately, the address space for the entire heap is reserved at startup. If it cannot reserve a large enough contiguous block of address space for the value of -Xmx that you pass it, it will fail to start. This is why it's tough to allocate >1.4GB heaps on 32-bit Windows - because it's hard to find contiguous address space in that size or larger, since some DLLs like to load in certain places, fragmenting the address space. This isn't really an issue when you go 64-bit, since there is so much more address space.

This is almost certainly for performance reasons. I could not find a terrific link detailing this further, but here is a pretty good quote from Peter Kessler (full link - be sure to read the comments) that I found when searching. I believe he works on the JVM at Sun.

The reason we need a contiguous memory region for the heap is that we have a bunch of side data structures that are indexed by (scaled) offsets from the start of the heap. For example, we track object reference updates with a "card mark array" that has one byte for each 512 bytes of heap. When we store a reference in the heap we have to mark the corresponding byte in the card mark array. We right shift the destination address of the store and use that to index the card mark array. Fun addressing arithmetic games you can't do in Java that you get to (have to :-) play in C++.

This was in 2004 - I'm not sure what's changed since then, but I am pretty sure it still holds. If you use a tool like Process Explorer, you can see that the virtual size (add the virtual size and private size memory columns) of the Java application includes the total heap size (plus other required space, no doubt) from the point of startup, even though the memory 'used' by the process will be no where near that until the heap starts to fill up...

这篇关于为什么Java堆的最大大小是固定的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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