设置java最大内存
关于堆(Heap)和非堆(Non-heap)内存
- 堆是Java内存管理的核心区域,所有类实例和数组的内存均从此处分配。
- 一个JVM实例只存在一个堆内存,在JVM启动时被创建。JVM堆之外的内存称为非堆内存(Non-heap memory)。
- 简单来说,堆就是Java代码可用的内存,非堆就是JVM留给自己用的。
关于jvm内存的相关参数:
参数 | 功能 | 备注 |
---|---|---|
-Xms128m | JVM初始分配的堆内存 | 等价于-XX:InitialHeapsize ,默认为物理内存1/64 |
-Xmx512m | JVM最大允许分配的堆内存,按需分配 | 等价于-XX:MaxHeapsize ,默认为物理内存1/4 |
-Xmn682m | 设置新生代的大小 | - |
-Xss128k | 设置每个线程的堆栈大小 | - |
-XX:PermSize=64m | JVM初始分配的非堆内存 | - |
-XX:MaxPermSize=128m | JVM最大允许分配的非堆内存,按需分配 | - |
-XX:+HeapDumpOnOutOfMemoryError | JVM发生OOM时自动生成dump文件 | - |
-XX:HeapDumpPath=./jvm.dump | 生成DUMP文件的路径 | 也可以指定文件名称 |
- 查看所有的参数的默认初始值
java -XX:+PrintFlagsInitial
- 至于 Xmx 最大可以设置多少,可用如下命令不断测试(比如设置2048m看是否报错)
[root@localhost ~]# java -Xmx2048m -version
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
[root@localhost ~]# java -Xmx2000g -version
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00007d5510000000, 67108864000, 0) failed; error='Cannot allocate memory' (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 67108864000 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /root/hs_err_pid12136.log
设置jvm堆大小实战
- 通常,使用Xms及Xmx限制初始内存及最大内存,以启动
api-gateway.jar
为例
cd /data/javapp/
nohup java -Xms4g -Xmx8g -jar api-gateway.jar > ./startup_`date +%Y%m%d%H`.log 2>&1 &
- 若要分析oom则建议配置如下,以启动
api-gateway.jar
为例
cd /data/javapp/
nohup java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./jvm.dump -Xms4g -Xmx8g -jar api-gateway.jar > ./startup_`date +%Y%m%d%H`.log 2>&1 &
- 这里推荐一款排查Java是否内存泄露的好工具,Arthas(Alibaba开源的Java诊断工具)。
java内存超过xmx指定
在实际业务中经常遇到 java 进程 -Xmx 指定了 2GB,但实际 top 里却用到了 3GB或更多,这是为什么呢?
- 当指定Java进程的-Xmx参数为2G时,表示Java堆内存的最大限制为2GB,然而,Java进程的总内存使用量可能会超过-Xmx参数指定的限制。
- 这是由于Java进程除了堆内存之外,还会使用其他内存区域,如方法区、线程栈、直接内存等。
- 此外,Java虚拟机本身也需要一些内存来维护数据结构、执行线程管理等操作。
因此,当您观察到Java进程的实际内存使用量超过了-Xmx参数指定的限制时,这是正常现象。