初始Java堆大小是什么意思?

4

我有一个使用Java堆的程序。

-Xms5g -Xmx12g 

我已设置初始的Java堆大小为5gb,最大堆大小为12gb。

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

所以这里有我的问题:

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

1
-Xms5g -Xmx12g;看起来你少了一个减号? - Boris the Spider
减号 ....,.? - Daniel
啊,那是我复制粘贴时犯的错误。应该有一个 "-" 符号。 - Daniel
我的问题更多的是,Java堆的初始工作原理是怎样的,因为我认为我理解错了? - Daniel
1
你正在使用哪个操作系统? - RealSkeptic
显示剩余2条评论
1个回答

5
-Xmx最大堆大小是堆能够增长到的最大大小。 -Xms初始堆大小是堆的范围。它不会在没有触发完整GC的情况下使用超过这个空间量。
然而,该堆被分成区域,例如您有一个5 GiB的初始堆,其中:
  • Eden大小为200 MB
  • 两个survivor空间为100 MB
  • tenured空间为4.6 GB。
当您开始使用内存时,Linux上需要的页面(4 KiB区域)将根据需求进行分配(除非您使用选项来预先触及它们)。
您的Eden空间将很快被占用,因此前200 MB将相当快地被使用(即使在调用main之前也会使用相当多)。一些大型对象直接进入tenured空间,但对于大多数应用程序,tenured空间主要由较小的长寿命对象占用。假设经过许多次minor collection后,约有100 MB的对象被提升到了tenured空间。
此时,即使范围为5 GB,也只有200 + 2 * 50 + 100 MB的内存被触摸或分配。
总之,Linux会懒惰地分配页面,因此必须写入它们以使用内存。

2
简而言之,Linux惰性地分配页面,因此您必须写入它们才能使用内存。另外,使用-XX:+ AlwaysPreTouch-Xms5g应该立即占用约5 GB的内存。 - Aleksey Shipilev
@AlekseyShipilev 如果最大值是“-Xmx12g”,它不会触及所有吗? - Peter Lawrey
1
我猜这取决于垃圾回收机制,但我认为它只会触及最初分配的部分,因此只涵盖-Xms的范围。 - Aleksey Shipilev
它不会使用超过此空间量而触发完整的GC。我认为G1可以添加区域而无需执行完整的GC。 - Philippe Marschall
在这种情况下,个人认为首字母缩写并不是很有意义。 - Peter Lawrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接