堆解决数据存储的问题,栈解决程序如何运行和数据如何处理的问题。
java堆是JVM内存中最大的一块,由所有线程共享,是由垃圾收集器管理的内存区域,主要存放对象实例
下图来自终于搞懂了Java8的内存结构,再也不纠结方法区和常量池了!
JAVA8 内存模型
JVM内存模型以及JDK7和JDK8内存模型对比总结
通过jmap分析内存泄漏
在linux下面才能执行的,windows中执行不了
# 什么类一直在增长,就是嫌疑犯了。windows只能写入到log中帅选了 jmap -histo 6220 > a.log # 在linux环境下可以执行 [root@wd8 ~]# jmap -histo:live 2547|head -n 10 num #instances #bytes class name ---------------------------------------------- 1: 13036 121602072 [B 2: 124376 18589896 [C 3: 22531 14658440 [Ljava.lang.Object; 4: 122682 2944368 java.lang.String 5: 8683 2380544 [I 6: 49152 2359296 com.alipay.sofa.jraft.core.FSMCallerImpl$ApplyTask 7: 68400 2188800 java.util.concurrent.ConcurrentHashMap$Node # 查看对象数最多的对象,按降序输出 jmap -histo pid | sort -k 2 -g -r # 查看内存的对象,按降序输出 jmap -histo pid | sort -k 3 -g -r
这里看一下nacos启动后,通过jmap -heap 8556查看堆的使用情况,下面是nacos中的默认jvm配置情况
set "NACOS_JVM_OPTS=-Xms512m -Xmx512m -Xmn256m"
集群下的配置
set "NACOS_JVM_OPTS=-server -Xms2g -Xmx2g -Xmn1g -XX:metaspaceSize=128m -XX:MaxmetaspaceSize=320m -XX:-OmitStackTraceInFastThrow -XX:+HeapDumponOutOfMemoryError -XX:HeapDumpPath=%base_DIR%logsjava_heapdump.hprof -XX:-UseLargePages"
下图做了windows和linux下面同一个nacos应用进程的堆使用情况
1 Parallel GC with 4 thread
JDK8的Parallel GC with 4 thread(s)的真正含义
2 NewRatio SurvivorRatio
JVM -XX:NewRatio、-XX:SurvivorRatio参数含义
JVM参数之SurvivorRatio和NewRatio
大家都知道Eden:survior from:survivor to的比例为8:1:1,SurvivorRatio中的8,表示就是这三个区域的比例
Eden+2*Survivor:Old的比值,即是NewRatio ,默认为2
可是为何上图中从capacity中看到单个进程比例完全不是这么回事。
JVM调优总结 -Xms -Xmx -Xmn -Xss
-Xms,就是上图的MaxHeapSize,最大可用内存
-Xmx,此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存
-Xmn,新生代(年轻代)的大小。
JDK1.8为什么废弃永久代【一篇就够】,jdk1.8以前还有个固定的64M的持久代,但现在被元数据空间替代了。由于永久代内存经常不够用或发生内存泄露,爆出异常java.lang.OutOfMemoryError: PermGen
从上图看到MaxmetaspaceSize = 17592186044415 MB,因为元数据空间使用的是本地内存,故而理论上没有上限。而metaspaceSize初始为20M
执行java -XX:+PrintFlagsInitial查看初始化了哪些东西,打印出来,但是也看不懂.
但元数据空闲上限默认很大,但因为它会占本地内存,故而对服务器上的应用会有影响,需要关注



