JVM内存学习 2.0

jvm,内存,学习 · 浏览次数 : 172

小编点评

# Generate Content **Content Generation** **Step 1: Native Memory Tracking** Total: 37718KB * 4 KB reserved for stack * 4 KB reserved for code cache **Step 2: Code Allocation** * 8 KB for 2.17.so * 8 KB for 2.17.so * 4 KB for 2.17.so * 4 KB for 2.17.so * 4 KB for 2.17.so * 4 KB for 2.17.so **Step 3: Address Allocation** * 4 KB for heap info * 12 KB for anonymous object * 4 KB for stack * 8 KB for 2.17.so * 4 KB for 2.17.so * 4 KB for 2.17.so * 4 KB for 2.17.so **Step 4: Object Allocation** * 20 KB for heap info * 24 KB for anonymous object * 4 KB for stack * 8 KB for 2.17.so * 4 KB for 2.17.so * 4 KB for 2.17.so **Step 5: Heap Info** * 16 KB for heap info * 8 KB for anonymous object * 4 KB for stack * 8 KB for 2.17.so **Step 6: Output** * Print content information * Print address allocation information * Print heap info

正文

先说一下结果

1. Linux的内存分配是惰性分配的. APP申明了 kernel并不会立即进行初始化和使用. 
2. JVM的内存主要分为, 堆区, 非堆区, 以及jvm使用的其他内存. 比如直接内存等.
3. top看到的内存与pmap 查询出来的内存基本一样. top的RES和pmap的RSS基本相同.
4. 堆区如果进行了合理的设置. 占用RSS或者是RES的比率在 70-77左右. 
5. 如果使用的功能比较集中, 可能codecache等内存使用量会少, 堆区占比会高
   如果全部功能遍历, 那么codecache 以及本地内存的缓存等就会比较大, 堆区的占比就会小.  
6. 如果使用容器的话 75% 应该算是一个基本合理的数值. 

摘要

最近中午帮某项目写docker下的启动脚本.
自己定义了几个参数. 但是感觉不太放心
怕出现因为堆外内存导致OOM的问题 
撑着有一个bug 需要不停的重启服务. 我就简单学习总结了下. 

主要用的工具其实就3类
1. jinfo,jcmd等命令查看JVM的信息.
   增加native_memory_track的设置. 查看summary等信息.  
2. pmap 从操作系统层查看内存的分配情况. 
3. top 等命令查看进程状态的信息. 

启动之前的结果

[root@centos7ver2009 gscloud]# jinfo 16732
Attaching to process ID 16732, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.222-b10
Java System Properties:

caf.startup.server.path.name = server
java.runtime.name = OpenJDK Runtime Environment
hibernate.jdbc.time_zone = Asia/Shanghai
java.vm.version = 25.222-b10
sun.boot.library.path = /gscloud/server/runtime/java/x86_64-linux/jre/lib/amd64
java.protocol.handler.pkgs = org.springframework.boot.loader
LOG_FILE_MAX_SIZE = 5MB
java.vendor.url = http://java.oracle.com/
java.vm.vendor = AdoptOpenJDK
path.separator = :
file.encoding.pkg = sun.io
java.vm.name = OpenJDK 64-Bit Server VM
sun.os.patch.level = unknown
sun.java.launcher = SUN_STANDARD
user.country = CN
user.dir = /gscloud
java.vm.specification.name = Java Virtual Machine Specification
PID = 16732
java.runtime.version = 1.8.0_222-b10
java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = /gscloud/server/runtime/java/x86_64-linux/jre/lib/endorsed
CONSOLE_LOG_CHARSET = UTF-8
spring.profiles.active = prod
line.separator = 

java.io.tmpdir = /tmp
java.vm.specification.vendor = Oracle Corporation
os.name = Linux
FILE_LOG_CHARSET = UTF-8
sun.jnu.encoding = UTF-8
java.library.path = /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
spring.beaninfo.ignore = true
java.class.version = 52.0
java.specification.name = Java Platform API Specification
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 3.10.0-1160.el7.x86_64
user.home = /root
user.timezone = Asia/Shanghai
LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE = 5242880
catalina.useNaming = false
java.awt.printerjob = sun.print.PSPrinterJob
file.encoding = UTF-8
java.specification.version = 1.8
catalina.home = /tmp/tomcat.5200.6719909097640900997
user.name = root
java.class.path = ./server/runtime/caf-bootstrap.jar
com.sun.org.apache.xml.internal.dtm.DTMManager = com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault
loader.path = ./server/runtime/3rd,./server/runtime/libs
server.runtime.path.name = /gscloud/server
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = ./server/runtime/caf-bootstrap.jar --spring.config.location=./server/runtime/
java.home = /gscloud/server/runtime/java/x86_64-linux/jre
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.X11.XToolkit
java.vm.info = mixed mode
java.version = 1.8.0_222
java.ext.dirs = /gscloud/server/runtime/java/x86_64-linux/jre/lib/ext:/usr/java/packages/lib/ext
sun.boot.class.path = /gscloud/server/runtime/java/x86_64-linux/jre/lib/resources.jar:/gscloud/server/runtime/java/x86_64-linux/jre/lib/rt.jar:/gscloud/server/runtime/java/x86_64-linux/jre/lib/sunrsasign.jar:/gscloud/server/runtime/java/x86_64-linux/jre/lib/jsse.jar:/gscloud/server/runtime/java/x86_64-linux/jre/lib/jce.jar:/gscloud/server/runtime/java/x86_64-linux/jre/lib/charsets.jar:/gscloud/server/runtime/java/x86_64-linux/jre/lib/jfr.jar:/gscloud/server/runtime/java/x86_64-linux/jre/classes
java.awt.headless = true
java.vendor = AdoptOpenJDK
catalina.base = /tmp/tomcat.5200.6719909097640900997
com.zaxxer.hikari.pool_number = 1
file.separator = /
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.font.fontmanager = sun.awt.X11FontManager
sun.cpu.endian = little
sun.cpu.isalist = 

VM Flags:
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=528482304 -XX:MaxHeapSize=8434745344 -XX:MaxNewSize=2811232256 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=176160768 -XX:OldSize=352321536 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
Command line:  -Dloader.path=./server/runtime/3rd,./server/runtime/libs -Dserver.runtime.path.name=server -Dspring.profiles.active=prod

修改启动配置节

  • 增加本地内存监控情况分析.
增加启动配置节:
 -XX:NativeMemoryTracking=summary
 -XX:+UnlockDiagnosticVMOptions
 -XX:+PrintNMTStatistics

然后进行验证. 

启动成功后查看堆区信息:

jcmd 3153 GC.heap_info
3153:
 PSYoungGen      total 2737664K, used 839841K [0x0000000718700000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 2732032K, 30% used [0x0000000718700000,0x000000074b5a9668,0x00000007bf300000)
  from space 5632K, 99% used [0x00000007bfa80000,0x00000007bffff070,0x00000007c0000000)
  to   space 6656K, 0% used [0x00000007bf300000,0x00000007bf300000,0x00000007bf980000)
 ParOldGen       total 3923968K, used 3679249K [0x00000005c9400000, 0x00000006b8c00000, 0x0000000718700000)
  object space 3923968K, 93% used [0x00000005c9400000,0x00000006a9d044b0,0x00000006b8c00000)
 Metaspace       used 930784K, capacity 955800K, committed 956056K, reserved 1904640K
  class space    used 94743K, capacity 100007K, committed 100016K, reserved 1048576K

查看JVM信息- 注意这个是启动成功还未使用时的情况

3153:

Native Memory Tracking:

Total: reserved=11485532KB, committed=8832628KB
-                 Java Heap (reserved=8237056KB, committed=6669312KB)
                            (mmap: reserved=8237056KB, committed=6669312KB) 
 
-                     Class (reserved=1924213KB, committed=975501KB)
                            (classes #129334)
                            (malloc=21621KB #196626) 
                            (mmap: reserved=1902592KB, committed=953880KB) 
 
-                    Thread (reserved=257096KB, committed=257096KB)
                            (thread #250)
                            (stack: reserved=255924KB, committed=255924KB)
                            (malloc=816KB #1253) 
                            (arena=356KB #495)
 
-                      Code (reserved=275156KB, committed=144832KB)
                            (malloc=25556KB #33396) 
                            (mmap: reserved=249600KB, committed=119276KB) 
 
-                        GC (reserved=309146KB, committed=303022KB)
                            (malloc=8198KB #3979) 
                            (mmap: reserved=300948KB, committed=294824KB) 
 
-                  Compiler (reserved=649KB, committed=649KB)
                            (malloc=518KB #3554) 
                            (arena=131KB #6)
 
-                  Internal (reserved=254240KB, committed=254240KB)
                            (malloc=254208KB #150391) 
                            (mmap: reserved=32KB, committed=32KB) 
 
-                    Symbol (reserved=186444KB, committed=186444KB)
                            (malloc=181993KB #2017141) 
                            (arena=4451KB #1)
 
-    Native Memory Tracking (reserved=37718KB, committed=37718KB)
                            (malloc=90KB #1100) 
                            (tracking overhead=37628KB)
 
-               Arena Chunk (reserved=3815KB, committed=3815KB)
                            (malloc=3815KB) 


通过top的方式进行查看

 top -Hp 3153 -bn 1  |head -n 10 
top - 17:22:12 up 105 days, 44 min,  6 users,  load average: 0.86, 1.33, 1.58
Threads: 250 total,   1 running, 249 sleeping,   0 stopped,   0 zombie
%Cpu(s): 16.7 us, 20.8 sy,  0.0 ni, 61.5 id,  0.0 wa,  0.0 hi,  1.0 si,  0.0 st
KiB Mem : 32946140 total,  4115820 free, 19413000 used,  9417320 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 12976944 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
 3153 root      20   0   14.4g   8.0g 116096 S  0.0 25.5   0:00.00 java
 3154 root      20   0   14.4g   8.0g 116096 S  0.0 25.5  25:46.31 java
 3155 root      20   0   14.4g   8.0g 116096 S  0.0 25.5   0:27.38 java

通过pmap查看内存使用情况

pmap -d $pid |tail -n 10 
Address           Kbytes     RSS   Dirty Mode  Mapping
00007f45727c2000       4       0       0 r----   [ anon ]
00007f45727c3000       4       4       4 rw---   [ anon ]
00007f45727c4000       4       4       4 r---- ld-2.17.so
00007f45727c5000       4       4       4 rw--- ld-2.17.so
00007f45727c6000       4       4       4 rw---   [ anon ]
00007ffddc929000     132      44      44 rw---   [ stack ]
00007ffddc9d4000       8       4       0 r-x--   [ anon ]
ffffffffff600000       4       0       0 r-x--   [ anon ]
---------------- ------- ------- ------- 
total kB         15106724 8408168 8292060

查看一个运行很多自动化的机器的内存使用情况

SQLSERVER数据库测试环境:
pmap的数值:         23686180
GC.heap_info的数值: 16683520
比率约为:  70%
机器的压力较大. 内存 94%

达梦数据库测试环境:
pmap的数值:         15449264
GC.heap_info的数值: 2005504+6867968
比率约为: 57%
机器的压力较小. 内存 80%

需要注意的是: 第二个是没有设置 Xmx的设置.
第一个设置了XMX还比较好一些. 

一个压测环境:
pmap的数值:         21518128
GC.heap_info的数值: 11086848+5490688 
比率约为: 77%
机器的压力较小. 内存 50%
这个环境跑的功能不是很多, 所以估计codecache等部分的占用会少一些. 

与JVM内存学习 2.0 相似的内容:

JVM内存学习 2.0

先说一下结果 1. Linux的内存分配是惰性分配的. APP申明了 kernel并不会立即进行初始化和使用. 2. JVM的内存主要分为, 堆区, 非堆区, 以及jvm使用的其他内存. 比如直接内存等. 3. top看到的内存与pmap 查询出来的内存基本一样. top的RES和pmap的RSS基

[转帖]jvm学习三-MAT内存分析工具的使用

目录 1 模拟内存溢出程序 1.1 jvm配置 1.2 测试代码 2 MAT工具进行内存分析 2.1 大纲介绍 2.2 Histogram视图介绍 2.3 Leak Suspects视图介绍 2.4 Dominator Tree 1 模拟内存溢出程序 1.1 jvm配置 -XX:+PrintGCDe

[转帖]JVM——内存区域:运行时数据区域详解

https://www.jianshu.com/p/cded765cfd1b 关注:CodingTechWork,一起学习进步。 引言 我们经常会被问到一个问题是Java和C++有何区别?我们除了能回答一个是面向对象、一个是面向过程编程以外,我们还会从底层内存管理和垃圾收集方面作出比较。 对于C++

JVM内存配置的再次思考

JVM内存配置的再次思考 摘要 最近研究过不少内存分配相关的处理 今天晚上突然感觉还不是非常系统. 还是想能够细致的在学习一下. 希望能够慢慢的拾遗,提高自己 操作系统内存的使用情况 本文主要想思考linux相关的. 暂时不考虑Windows相关的机器配置. 也不考虑混用的情况 仅考虑专用的应用服务

[转帖]JVM系列之:你知道Java有多少种内存溢出吗

本文为《深入学习 JVM 系列》第二十五篇文章 Java内存区域 关于这部分内容大多来源于《深入理解Java虚拟机》一书。 Java 运行时数据区域(JDK8)如下图所示: 关于上述提到的线程共享和线程隔离区域,下图做详细讲解: 程序计数器 程序计数器是一块较小的内存空间,可以看作是当前线程所执行的

[转帖]为什么说JVM是黑盒子般存在,从Java 虚拟机原理内存开始

https://maimai.cn/article/detail?fid=1739907745&efid=ALbQzkwOvQr-0GryeUzRsw 为什么要学习 JVM 在很多 Java 程序员的开发生涯里,JVM 一直是黑盒子一般的存在,大家只知道运行 Java 程序需要依靠 JVM,千篇一律

[转帖]JVM 使用mat分析Dump文件排查大对象解决系统full GC问题

https://www.cnblogs.com/east7/p/16989436.html 摘要:介绍内存分析工具Mat查找大对象的使用方法,定位full GC根源,拉升系统吞吐量,避免内存泄漏。 引言 线上服务器频繁发生full GC,直接拉低系统吞吐量,甚至OOM。今天我们来一起学习一下如何利用

[转帖]JVM 使用mat分析Dump文件排查大对象解决系统full GC问题

https://www.cnblogs.com/east7/p/16989436.html 摘要:介绍内存分析工具Mat查找大对象的使用方法,定位full GC根源,拉升系统吞吐量,避免内存泄漏。 引言 线上服务器频繁发生full GC,直接拉低系统吞吐量,甚至OOM。今天我们来一起学习一下如何利用

[转帖]JVM 使用mat分析Dump文件排查大对象解决系统full GC问题

https://www.cnblogs.com/east7/p/16989436.html 摘要:介绍内存分析工具Mat查找大对象的使用方法,定位full GC根源,拉升系统吞吐量,避免内存泄漏。 引言 线上服务器频繁发生full GC,直接拉低系统吞吐量,甚至OOM。今天我们来一起学习一下如何利用

[转帖]Eclipse-MAT的插件介绍使用

学习 尚硅谷 宋红康 JVM从入门到精通 的学习笔记 概述 MAT (Memory Analyzer Tool ) 工具是一款功能强大的Java堆内存分析器.可以用于查找内存泄露以及查看内存消耗情况. MAT是基于Eclipse开发的,不仅仅可以单独使用,还可以作为插件的形式内嵌在Eclipse中使