初始Java堆大小意味着什么?

Dan*_*iel 4 java jvm heap-memory

所以我有一个使用Java堆的程序

-Xms5g -Xmx12g 
Run Code Online (Sandbox Code Playgroud)

我已将初始 Java 堆大小设置为 5GB,最大堆大小设置为 12GB

但是当我查看任务管理器或资源监视器时,我的程序仅使用 400mb。

这是我的问题:

  1. 初始 Java 堆大小意味着什么?
  2. 为什么如果我将初始 Java 堆大小设置为 5GB,我只看到程序的 RAM 使用量为 400MB,难道不应该是 5GB 吗?因为初始堆意味着最小大小,对吗?

Pet*_*rey 5

-Xmx堆大小是堆可以增长到的最大大小。

初始堆大小-Xms是堆范围的大小。在不触发完整 GC 的情况下,它不会使用超过此数量的空间。

然而,这个堆被分为多个区域,例如,假设您有一个 5 GiB 的初始堆,其中

  • Eden 大小为 200 MB
  • 两个 100 MB 的幸存者空间
  • 4.6 GB 的永久空间。

当您开始使用内存时,所触及的页面(4 KiB 区域)将在 Linux 上按需分配(除非您使用选项来预触及所有页面)

main您的 Eden 空间将很快被使用,因此前 200 MB 会很快被使用(如果在调用之前就使用了相当多)。幸存者空间将在几次小收集后使用,但最初它们可能不会全部被触及,例如,假设它们从未填充到每个超过 50 MB(可用的 100 MB 中),此时触及的总内存为 200 MB + 2 * 50 MB。

一些大型对象直接进入永久空间,但是对于大多数应用来说,永久空间主要被较小的、寿命较长的对象占据。假设在多次小型回收之后,大约 100 MB 的对象已提升为永久空间。

此时,即使范围为 5 GB,也仅触及或分配了 200 + 2 * 50 + 100 MB 内存。

简而言之,Linux 延迟分配页面,因此您必须写入它们才能使用内存。

  • “简而言之,Linux 会延迟分配页面,因此您必须写入它们才能使用内存。” 添加:使用 `-XX:+AlwaysPreTouch`,并且 `-Xms5g` 应该立即占用约 5 GB。 (2认同)