jvm的内存

jvm的内存模型

1.JDK1.7的堆内存模型

  • Young年轻区(代)

    Young区被划分为三部分,Eden区和两个大小严格相同的Survivor区,其中,Survivor区间中,某一时刻只有其中一个是被使用的,另一个用作垃圾收集时复制对象使用,在Eden区变满时,GC就会将存活的对象移动到空闲的Survivor区间中,根据jvm的策略,经历几次垃圾收集后,任然存在于Survivor的对象将被移动到Tenured区间

  • Tenured年老区

    Tenured区主要保存生命周期长的对象,一般是一些老的对象,当一些对象在Young区复制转移一定次数以后,对象就会被转移到Tenured区,一般如果系统中用了application级别的缓存,缓存中的对象往往会被转移到这一区间。

  • Perm永久区

    Perm代主要保存class,method,filed这些对象,这部分空间一般不会溢出,除非一次性加载了很多类,不过在涉及到热部署的应用服务器的时候,有时候可能会遇到java.lang.OutOfMemoryError:PermGen space 的错误造成这个错误的很大原因就有可能是每次都重新部署,但是重新部署后,类的class没有被卸载掉,这就造成了大量的class对象保存在了perm中,这种情况,一般重启应用服务器就可以解决了。

  • Virtual区:

    • 最大内存和初始呢村的差值,就是Virtual区

2.JDK1.8的堆内存模型

jdk1.8内存模型的年轻代(Eden+2*Survivor)和年老代(OldGen)和1.7类似,最大的变化是Perm区被Metaspace(元数据空间)进行了替换,Metaspace所占用的内存空间不是在虚拟机内部,而是在本地内存空间中,这也是与1.7永久代的最大区别之处。

3.为什么要废除1.7中的永久区

由于永久代内存经常不够用或发生内存泄露,爆出异常java.lang.OutOfMemoryError:PermGen 所以将永久区废弃,而改用元空间,改为使用了本地内存空间。

4.通过jstat命令进行查询堆内存使用情况

jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令格式如下:

jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]

4.1查看class加载统计

[root@iZ8vb9fnmvw0un4s5l6adsZ ~]# jps
16919 ResourceManager
19657 Bootstrap
8236 Jps
[root@iZ8vb9fnmvw0un4s5l6adsZ ~]# jstat -class 19657
Loaded  Bytes  Unloaded  Bytes     Time   
  3120  6131.3       13    16.6       2.06

说明:

  • Loaded:加载class的数量
  • Bytes:所占用空间大小
  • Unloaded:未加载数量
  • Bytes:未加载占用空间
  • Time:时间

4.2查看编译统计

[root@iZ8vb9fnmvw0un4s5l6adsZ ~]# jstat -compiler 19657
Compiled Failed Invalid   Time   FailedType FailedMethod
    4710      0       0    18.33          0  

说明:

  • Compiled:编译数量
  • Failed:失败数量
  • Invalid:不可用数量
  • Time:时间
  • FailedType:失败类型
  • FailedMethod:失败的方法

4.3垃圾回收统计

[root@iZ8vb9fnmvw0un4s5l6adsZ ~]# jstat -gc 19657
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
1024.0 1024.0  46.2   0.0    8256.0   2019.2   20480.0    13875.6   21504.0 20684.4 2304.0 2097.3   6712   12.971   3      0.115   13.086
# 指定打印间隔和次数,每秒打印一次,供打印5次
[root@iZ8vb9fnmvw0un4s5l6adsZ ~]# jstat -gc 19657
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
1024.0 1024.0  46.2   0.0    8256.0   2019.2   20480.0    13875.6   21504.0 20684.4 2304.0 2097.3   6712   12.971   3      0.115   13.086
[root@iZ8vb9fnmvw0un4s5l6adsZ ~]# jstat -gc 19657 1000 5
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
1024.0 1024.0  46.2   0.0    8256.0   2847.5   20480.0    13875.6   21504.0 20684.4 2304.0 2097.3   6712   12.971   3      0.115   13.086
1024.0 1024.0  46.2   0.0    8256.0   2847.5   20480.0    13875.6   21504.0 20684.4 2304.0 2097.3   6712   12.971   3      0.115   13.086
1024.0 1024.0  46.2   0.0    8256.0   2847.5   20480.0    13875.6   21504.0 20684.4 2304.0 2097.3   6712   12.971   3      0.115   13.086
1024.0 1024.0  46.2   0.0    8256.0   2847.5   20480.0    13875.6   21504.0 20684.4 2304.0 2097.3   6712   12.971   3      0.115   13.086
1024.0 1024.0  46.2   0.0    8256.0   2847.5   20480.0    13875.6   21504.0 20684.4 2304.0 2097.3   6712   12.971   3      0.115   13.086

说明:

  • S0C:第一个Survivor区的大小(KB)
  • S1C:第二个Survivor区的大小(KB)
  • S0U:第一个Survivor区的使用大小(KB)
  • S1U:第二个Survivor区的使用大小(KB)
  • EC:Eden区的大小
  • EU:Eden区的使用大小
  • OC:Old区的大小
  • OU:Old区的使用大小
  • MC:方法区的大小
  • MU:方法区的使用大小
  • CCSC:压缩类空间大小
  • CCSU:压缩类空间使用大小
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗的时间
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

jmap的使用以及内存溢出分析

1.查看内存使用情况

前面通过jstat可以对jvm堆的内存进行统计分析,而jmap可以获取到更加详细的内容,如:内存使用情况汇总、对内存溢出的定位于分析。

[root@iZ8vb9fnmvw0un4s5l6adsZ ~]# jps
16919 ResourceManager
19657 Bootstrap
22156 Jps
[root@iZ8vb9fnmvw0un4s5l6adsZ ~]# jmap -heap 19657
Attaching to process ID 19657, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.144-b01

using thread-local object allocation.
Mark Sweep Compact GC

Heap Configuration:# 堆内存配置信息
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 482344960 (460.0MB)
   NewSize                  = 10485760 (10.0MB)
   MaxNewSize               = 160759808 (153.3125MB)
   OldSize                  = 20971520 (20.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:#堆内存的使用情况
New Generation (Eden + 1 Survivor Space):
   capacity = 9502720 (9.0625MB)
   used     = 8333272 (7.947227478027344MB)
   free     = 1169448 (1.1152725219726562MB)
   87.69354458512932% used
Eden Space:
   capacity = 8454144 (8.0625MB)
   used     = 8284672 (7.90087890625MB)
   free     = 169472 (0.16162109375MB)
   97.9953972868217% used
From Space:
   capacity = 1048576 (1.0MB)
   used     = 48600 (0.04634857177734375MB)
   free     = 999976 (0.9536514282226562MB)
   4.634857177734375% used
To Space:
   capacity = 1048576 (1.0MB)
   used     = 0 (0.0MB)
   free     = 1048576 (1.0MB)
   0.0% used
tenured generation:
   capacity = 20971520 (20.0MB)
   used     = 14209184 (13.550933837890625MB)
   free     = 6762336 (6.449066162109375MB)
   67.75466918945312% used

2. 查看内存中对象数量及大小

# 查看所有对象,包括活跃以及非活跃的
jmap -histo <pid> | more

#查看活跃对象
jmap -histo:live <pid> | more
[root@iZ8vb9fnmvw0un4s5l6adsZ ~]# jmap -histo:live 19657 | more

 num     #instances         #bytes  class name
----------------------------------------------
   1:         30817        3095376  [C
   2:          1269        1785536  [B
   3:         30529         732696  java.lang.String
   4:         15723         503136  java.util.HashMap$Node
   5:          4537         399256  java.lang.reflect.Method
   6:          3459         391576  java.lang.Class
   7:          7667         245344  java.util.concurrent.ConcurrentHashMap$Node
   8:          4276         239664  [Ljava.lang.Object;
   9:           910         189336  [Ljava.util.HashMap$Node;
  10:          2071         159064  [I
  11:           101         105840  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  12:          1189         104632  org.apache.catalina.webresources.CachedResource
  13:          5203          83248  java.lang.Object
  14:          1600          76800  java.util.HashMap
  15:          1039          56416  [Ljava.lang.String;
  16:          2497          53056  [Ljava.lang.Class;
  17:            92          49664  [Ljava.util.WeakHashMap$Entry;
  18:          1452          46464  java.util.Hashtable$Entry
  19:           903          43344  org.apache.tomcat.util.modeler.AttributeInfo
  20:          1082          43280  java.util.LinkedHashMap$Entry
  21:            10          41120  [Ljava.nio.ByteBuffer;
  22:          1232          39424  java.io.File
  23:          1086          34752  java.lang.ref.WeakReference


#对象说明
B byte
C char
D double
F float
I int
J long
Z boolean
[ 数组,如[I 表示 int[]
[L+类名 其他对象

3.将内存使用情况dump到文件中

# 用法:
jmap -dump:format=b,file=dumpFileName <pid>
# 示例
[root@iZ8vb9fnmvw0un4s5l6adsZ zyh]# jps
22997 Jps
16919 ResourceManager
19657 Bootstrap
[root@iZ8vb9fnmvw0un4s5l6adsZ zyh]# jmap -dump:format=b,file=/home/zyh/dump.dat 19657
Dumping heap to /home/zyh/dump.dat ...
Heap dump file created
[root@iZ8vb9fnmvw0un4s5l6adsZ zyh]# ls
conf.d  dump.dat  go  jvm  myweb  shell

4.通过jhat对dump文件进行解析

# 用法:
jhat -port <port> <file>

#示例:
[root@iZ8vb9fnmvw0un4s5l6adsZ zyh]# jhat -port 9999 /home/zyh/dump.dat 
Reading from /home/zyh/dump.dat...
Dump file created Fri Dec 31 15:56:29 CST 2021
Snapshot read, resolving...
Resolving 226609 objects...
Chasing references, expect 45 dots.............................................
Eliminating duplicate references.............................................
Snapshot resolved.
Started HTTP server on port 9999
Server is ready.
# 打开浏览器访问:ip:9999
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值