网上大多数地方,我得到有关堆参数的信息
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
当我提到-Xms 512M -Xmx 2048M
参数时,这是我的理解/问题,
-Xms: - 我的理解是如果我的java进程实际上只需要200M,提到-Xms 512M,java进程仍将只分配200M(需要实际内存)而不是500M 。但是如果我已经知道我的应用程序将在启动时使用这个512M内存,那么指定少于将对性能产生影响,因为无论如何堆块需要调整大小,这是昂贵的操作。
与我的同事进行讨论,默认情况下,GC会触发60%的Xms值。那是对的吗 ?如果是,是次要GC还是完全GC依赖于Xms值?
Xms更新: 在阅读JVM heap parameters之后,这似乎是正确的,但默认情况下值是60%,并且是依赖于Xms值的次要GC还是完整GC?
-Xmx: - 我的理解是提到-Xmx 2048M,java进程实际上是要从操作系统中保留2048M内存供其使用,因为另一个进程无法获得其共享。如果无论如何需要超过2048M内存的java进程,然后会抛出内存不足。
另外我相信全GC触发器与-Xmx的值有一些关系。因为我观察到的是当内存达到Xmx的70%时,Full GC发生在jconsole中。这是对的吗?
配置: - 我使用的是linux box(64位JVM 8)。默认GC即平行GC
答案 0 :(得分:3)
仅基于Xms或Xmx值不会触发GC。
Heap = New + Old generation
堆大小(最初设置为Xms)分为2代 - 新(又名Young)和Old(又名Tenured)。默认情况下,新一代是总堆大小的1/3,而旧一代是堆大小的2/3。这可以通过使用名为NewRatio的JVM参数进行调整。其默认值为2.
Young Generation进一步划分为Eden和2个Survivor空间。这3个空格的默认比例为:3 / 4,1 / 8,1 / 8。
旁注:这是关于并行GC收集器的。对于G1 - 新的GC算法以不同方式划分堆空间。
次要GC 所有新对象都在Eden空间中分配(除了直接存储在Old代中的大型对象)。当Eden空间变满时,将触发Minor GC。存在多个次要GC的对象将被提升为旧生成(默认为15个周期,可以使用JVM参数更改:MaxTenuringThreshold)。
主要GC 与并发收集器不同,其中主要GC基于已用空间触发(默认为70%),并行收集器根据下面提到的3个目标计算阈值。
并行收集者目标
因此,默认情况下,并行收集器尝试在垃圾收集中花费最多1%的应用程序运行时间。
更多详情here
Xms到Xmx
在启动期间,JVM会创建大小为Xms的堆,但保留额外的空间(Xmx)以便以后增长。该保留空间称为虚拟空间。请注意,它只是保留空间而不提交。
2个参数决定堆大小在Xms和Xmx之间增长(或收缩)的时间。
PS :JVM GC是一个引人入胜的主题,我建议您阅读此excellent article以深入了解。可以找到所有JVM调整参数here。