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

为什么Java堆的最大大小是固定的?

黄弘盛
2023-03-14
问题内容

这是 不是
增加Java的堆的最大尺寸的虚拟机启动后。技术原因是什么?垃圾回收算法是否取决于要使用固定数量的内存?还是出于安全原因,通过消耗所有可用内存来防止Java应用程序从DOS的系统中移至其他应用程序?


问题答案:

最后我知道在Sun的JVM中,必须在连续的地址空间中分配整个堆。我想对于大堆值,很难在启动后将其添加到您的地址空间中,同时又要确保它保持连续。您可能需要在启动时获取它,或者根本不需要。因此,它是固定的。

即使不是立即全部使用,启动时也会保留整个堆的地址空间。如果它不能为传递的-
Xmx值保留足够大的连续地址空间块,它将无法启动。这就是为什么很难在32位Windows上分配大于1.4GB的堆的原因-
因为很难找到该大小或更大大小的连续地址空间,因为某些DLL喜欢在某些地方加载,从而使地址空间碎片化。当您使用64位时,这并不是真正的问题,因为有更多的地址空间。

这几乎可以肯定是出于性能方面的考虑。我找不到很棒的链接来详细说明这一点,但是这是我在搜索时找到的彼得·凯斯勒(Peter
Kessler)的一个不错的报价(完整链接
-请务必阅读评论)。我相信他在Sun的JVM上工作。

之所以需要为堆使用连续的内存区域,是因为我们有一堆副数据结构,这些数据结构从堆开始处按(缩放的)偏移量进行索引。例如,我们使用“卡片标记数组”跟踪对象引用更新,该“卡片标记数组”每512字节堆有一个字节。当我们将引用存储在堆中时,我们必须在卡标记数组中标记相应的字节。我们右移商店的目标地址,并用它来索引卡标记阵列。用C
++玩(必须:-)玩Java不能解决的有趣的算术游戏。

那是在2004年-我不确定此后发生了什么变化,但是我很确定它仍然成立。如果您使用诸如Process
Explorer之类的工具,则可以看到Java应用程序的虚拟大小(添加虚拟大小和私有大小内存列)从启动时就包括了总堆大小(无疑还有其他所需的空间)。
,即使该进程“使用”的内存在堆开始填满之前也离它不远…



 类似资料:
  • 问题内容: 我有两台linux机器(都是VM),一台有12GB内存,另一台有8GB内存。 我试图在两台机器上启动相同的Java程序,并且最大可能的最大堆大小(使用-Xmx标志)。以下是我得到的结果。 12GB机器:9460MB 8GB机器:4790MB 如果我指定的最大堆大小超出了限制,我将得到以下错误。 我检查了两个系统中的可用内存(使用命令),然后得到关注。 12GB机器:大约3GB可用空间。

  • 我是Java的初学者,刚开始使用Intellij作为我的IDE。 当我使用它时,有时会延迟。 我更改了我的 xms 和 xmx 以获得更大的堆大小(xms = 1024,xmx = 2048),但它抛出了一个错误。 所以,我把它回滚了。 错误消息是这样的:“初始堆大小设置为大于最大堆大小的值”。 有什么问题? 如果可能,如何增加最大堆大小? 我用的是笔记本电脑,它有8GB内存。x64Intelli

  • 我一直想知道为什么STL优先级队列默认使用最大堆而不是最小堆。我想到的两个明显的用例是寻路(Dijkstra)和构建霍夫曼代码。这两种算法都需要首先拉取最小元素。由于排序(std::sort)默认使用升序,我想知道priority_queue背后的设计原因是什么,因为我非常喜欢默认的最小堆。

  • 问题内容: 我想用Java创建一个Stack,但是要固定大小。例如,创建一个新的堆栈,将大小设置为10,然后在将项目推入堆栈时将其填满,并在将其填满到十时将堆栈中的最后一个项目推出(移出)。我想使用Stack,因为它使用LIFO,非常适合我的需求。 但是Stack从Vector继承的setSize()方法似乎并没有真正限制Stack的大小。我想我缺少有关堆栈如何工作的信息,或者堆栈并不是要受到约束

  • 我有两台Linux机器(都是虚拟机),一台有12GB内存,另一台有8GB内存。 我尝试在两台机器上启动相同的java程序,并尽可能地使用最大堆大小(使用-Xmx标志)。以下是我得到的结果。 12GB 机器容量: 9460MB 8GB 机器容量: 4790MB 如果我指定的最大堆大小超出了上述限制,我会得到以下错误。 我检查了两个系统中的空闲内存(使用< code>free命令),得到如下结果。 <

  • 我刚刚在VServer和JRE Build1.7.0_67-B01上安装了Ubuntu 64bit。如果我想运行一个java jar文件,它说 无效的最大堆大小:-XMX错误:无法创建Java虚拟机。错误:发生致命异常。程序将退出。 我试了1M,256M,1024M,2G和4G的-XMX,都不起作用。是不是有我不知道的隐藏设定? 下面是我使用的命令: