CATALINA_OPTS="-Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=1024m"
export CATALINA_OPTS
JAVA_OPTS="-Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=1024m"
export JAVA_OPTS
说明:
-Xms = 初始值
-Xmx = 最大值
-Xmn = 最小值
-XX:PermSize = 设定记忆体的永久保存区域
-XX:MaxPermSize = 设定最大记忆体的永久保存区域
-XX:MaxNewSize = 设置新域的最大值
Xms 、Xmx、XX:PermSize、XX:MaxPermSize 各个引数的含义;
我们首先了解一下 JVM 记忆体管理的机制,然后再解释每个引数代表的含义。
堆(Heap)和非堆(Non-heap)记忆体:
按照官方的说法
Java 虚拟机器具有一个堆,堆是执行时资料区域,所有类例项和阵列的记忆体均从此处分配,堆是在 Java 虚拟机器启动时建立的,在 JVM 中堆之外的记忆体称为非堆记忆体(Non-heap memory)。
可以看出 JVM 主要管理两种型别的记忆体:堆和非堆。
堆就是 Java 程式码可及的记忆体,是留给开发人员使用的,非堆就是 JVM 留给自己用的,所以方法区、JVM 内部处理或优化所需的记忆体(如 JIT 编译后的程式码快取)、每个类结构(如执行时常数池、栏位和方法资料)以及方法和构造方法的程式码都在非堆记忆体中。
堆记忆体分配
JVM 初始分配的记忆体由 -Xms 指定,预设是实体记忆体的1/64,JVM 最大分配的记忆体由-Xmx 指定,预设是实体记忆体的1/4,预设空余堆记忆体小于40%时,JVM 就会增大堆直到-Xmx 的最大限制。
空余堆记忆体大于70%时,JVM 会减少堆直到 -Xms 的最小限制,因此伺服器一般设定-Xms、-Xmx 相等以避免在每次 GC 后调整堆的大小。
非堆记忆体分配
JVM 使用 -XX:PermSize 设定非堆记忆体初始值,预设是实体记忆体的1/64,由X:MaxPermSize 设定最大非堆记忆体的大小,预设是实体记忆体的1/4。
JVM 记忆体限制(最大值):
首先 JVM 记忆体限制于实际的最大实体记忆体,假设实体记忆体无限大的话,JVM 记忆体的最大值跟作业系统有很大的关係。
简单的说就32bit处理器虽然可控记忆体空间有4GB,但是具体的作业系统会给一个限制,这个限制一般是2GB-3GB(一般来说 Windows 系统下为1.5G-2G,Linux 系统下为2G-3G),而64bit以上的处理器就不会有限制了。
有的机器将 -Xmx 和 -XX:MaxPermSize 都设定为512M之后 tomcat 可以启动,而有些机器无法启动?
通过上面对 JVM 记忆体管理的介绍我们已经了解到 JVM 记忆体包含两种:堆记忆体和非堆记忆体,另外 JVM 最大记忆体首先取决于实际的实体记忆体和作业系统。
所以说设定 VM 引数导致程序无法启动主要有以下几种原因:
(1) 引数中 -Xms 的值大于 -Xmx,或者 -XX:PermSize 的值大于 -XX:MaxPermSize
(2) -Xmx 的值和 -XX:MaxPermSize 的总和超过了 JVM 记忆体的最大限制,比如当前作业系统最大记忆体限制,或者实际的实体记忆体等等。
说到实际实体记忆体这里需要说明一点的是,如果你的记忆体是1024MB,但实际系统中用到的并不可能是1024MB,因为有一部分被硬体佔用了。