注意:存活数据是指,应用处于稳定运行状态下,在Java堆里面长期存活的对象。换一句话说,就是应用在稳定运行的状态下,Full GC之后,Java堆的所占的空间。
约束
有多少物理内存可以供JVM使用?是部署多个JVM或者单个JVM?对做出的决定有重要影响。下面列出了一些要点可以帮助决定有多少物理内存可以供使用。
1、一个机器上面只是部署一个JVM,且就一个应用使用?如果是这种情况,那么机器的所有物理内存可以供JVM使用。
2、一个机器上部署了多个JVM?或者一个机器上部署了多个应用?如果是这两个中的任何一种情况,你就必须要决定每一个JVM或者应用需要分配多少内存了。
无论是前面的哪种情况,都需要给操作系统留出一些内存。
HotSpot VM的堆结构
在做内存占用测量之前,我们必须要先理解HotSpot VM Java堆的结构,理解这个对决定应用需要的Java堆大小以及优化垃圾收器性能有很好的帮助。
HotSpot VM有3个主要的空间:young代、old代以及permanent代,如上图所示。
当Java应用分配Java对象时,这些对象被分配到young代。在经历过几次minor GC之后,如果对象还是存活的,就会被转移到old代空间。permanent代空间存储了VM和Java类的元数据比如内置的字符串和类的静态变量。
-Xmx和-Xms这个两个命令行选项分别指定yound代加上old代空间的总和的初始最大值和最小值,也就是Java堆的大小。当-Xms的值小于-Xmx的值的时候,Java堆的大小可以在最大值和最小值之前浮动。当Java应用强调吞吐量和延迟的时候,倾向于把-Xms和-Xmx设置成相同的值,由于调整young代或者old代的大小都需要进行Full GC,Full GC降低吞吐量以及加强延迟。
young代的空间可以通过下面的任意一个命令行选项来设置:
1、-XX:NewSize=[g|m|k]
young代的初始值和最小值。是大小,[g|m|k]表示单位是G字节,M字节或者千字节。young代的大小不会小于这个值。当设定-XX:NewSize=[g|m|k]的时候,-XX:MaxNewSize=[g|m|k]需要被指定。
2、-XX:MaxNewSize=[g|m|k]
young区空间的最大值。同上面反过来,当指定-XX:MaxNewSize=[g|m|k]的需要指定-XX:NewSize=[g|m|k]。
3、-Xmn[g|m|k]
直接指定young代的初始值、最小值以及最大值。也就是说,young区的大小被固定成这个值了。这个值用来锁定young代的大小很方便。