JVM中对象存储分析

  • 基础知识:

JVM中的实例化对象是存储在heap中的,heap分为,新生代和年长代,新生代又分为(eden、survivor1、survivor0),年长代又称作tenured space,存放经历多次minor gc回收以后,仍然存活的对象,方法区又称为永久区,用于存放class  meta相关的全限定类名、方法名、修饰符、常量、参数类型、类成员变量等,这些基础知识相信大家并不陌生,本文主要介绍的是创建一个对象,对JVM存储产生的变化。

  • 存储分析

根据以上基础知识,得出结论:

1、创建一个对象会增加heap区的存储占用

2、如果创建的多个实例,同属同一个class,由于是属于同一个class,所以对PermGen即永久区不会产生影响

论证的流程如下:

1、创建一个名为Jvm的自定义类对象,完成后,观察heap区和PermGen的占用,获取此时的存活对象的个数和占用字节数

2、创建1000个名为Jvm的自定义对象,完成后,观察heap区和PermGen的占用,获取此时的存活对象的个数和占用字节数

3、拿两次heap区和PermGen的已用内存变动做差值比较,多出来的存储内容,理论上就是由多创建出的999个JVM对象产生的

4、拿两次存活对象占用空间做差值比较,得出的差值==两次heap区的已用内存的差值

5、以上的两次采集的内容,需要保证:

5.1、heap已用内存的占用采样收集到的对象个和占用空间的采样必须保证是在Jvm对象创建完毕以后进行采集

5.2、收集到的对象必须是保证全部是存活对象

如上5.1的条件比较容易实现,只需要在自定义类Jvm的全部实例化完成后,调用jmap -heap获取当前的堆存储情况即可,保证5.2的条件方式有两种:

5.2.1一种是使用jmap -histo:live,这种方式在目前的场景下有个缺陷是,执行完这个命令会触发fullgc、这样会导致本次测试用例中的Jvm实例强制回收,这样会出现统计出的heap是包含自定义对象的存储占用,而统计出的对象则不包含自定义对象,所以考虑采用5.2.2方式

5.2.2统计出所有对象的个数和占用比使用jmap -heap命令,增加附加条件,保证在此期间不发生GC,使用jstat -gcutil进行监控GC情况

  • 验证过程

 先上测试代码:

1、自定义Class

package com.tt.st.jvm;

public class Jvm {

}

2、Main 

package com.tt.st.jvm;

import java.util.ArrayList;
import java.util.List;

public class Main {
	private List<Jvm> list = new ArrayList<>();
	
	public static void main(String[] args) throws Exception {
		Main main = new Main();
		int k = Integer.parseInt(args[0]);
		main.ok(k);
		
	}

	private void ok(int k) throws Exception{
		for(int j=1;j<=k;j++) {
			Jvm jvm = new Jvm();
			list.add(jvm);
		}
		System.out.println("init complete");
		Thread.sleep(10*1000l);
	}
}

3、执行脚本liveClc.sh:

pid=$(ps -ef | grep java | awk 'NR==1 {print $2}')
jmap -heap $pid >>b.txt
jmap -histo $pid >>c.txt
jstat -gcutil $pid>>e.txt

4、执行命令:

4.1、java -Xms2m -Xmx2m com/tt/st/jvm/Main 1000

4.2、./liveClc.sh

4.3、java -Xms2m -Xmx2m com/tt/st/jvm/Main 1

4.4、./liveClc.sh

5、差值比较:


Heap Configuration:
   MinHeapFreeRatio = 0
   MaxHeapFreeRatio = 100
   MaxHeapSize      = 8388608 (8.0MB)
   NewSize          = 1310720 (1.25MB)
   MaxNewSize       = 17592186044415 MB
   OldSize          = 5439488 (5.1875MB)
   NewRatio         = 2
   SurvivorRatio    = 8
   PermSize         = 21757952 (20.75MB)
   MaxPermSize      = 85983232 (82.0MB)
   G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 2097152 (2.0MB)
   used     = 428528 (0.4086761474609375MB)
   free     = 1668624 (1.5913238525390625MB)
   20.433807373046875% used
From Space:
   capacity = 524288 (0.5MB)
   used     = 0 (0.0MB)
   free     = 524288 (0.5MB)
   0.0% used
To Space:
   capacity = 524288 (0.5MB)
   used     = 0 (0.0MB)
   free     = 524288 (0.5MB)
   0.0% used
PS Old Generation
   capacity = 1048576 (1.0MB)
   used     = 0 (0.0MB)
   free     = 1048576 (1.0MB)
   0.0% used
PS Perm Generation
   capacity = 22020096 (21.0MB)
   used     = 2701672 (2.5765151977539062MB)
   free     = 19318424 (18.423484802246094MB)
   12.269119989304315% used


Heap Configuration:
   MinHeapFreeRatio = 0
   MaxHeapFreeRatio = 100
   MaxHeapSize      = 8388608 (8.0MB)
   NewSize          = 1310720 (1.25MB)
   MaxNewSize       = 17592186044415 MB
   OldSize          = 5439488 (5.1875MB)
   NewRatio         = 2
   SurvivorRatio    = 8
   PermSize         = 21757952 (20.75MB)
   MaxPermSize      = 85983232 (82.0MB)
   G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 2097152 (2.0MB)
   used     = 381192 (0.36353302001953125MB)
   free     = 1715960 (1.6364669799804688MB)
   18.176651000976562% used
From Space:
   capacity = 524288 (0.5MB)
   used     = 0 (0.0MB)
   free     = 524288 (0.5MB)
   0.0% used
To Space:
   capacity = 524288 (0.5MB)
   used     = 0 (0.0MB)
   free     = 524288 (0.5MB)
   0.0% used
PS Old Generation
   capacity = 1048576 (1.0MB)
   used     = 0 (0.0MB)
   free     = 1048576 (1.0MB)
   0.0% used
PS Perm Generation
   capacity = 22020096 (21.0MB)
   used     = 2701672 (2.5765151977539062MB)
   free     = 19318424 (18.423484802246094MB)
   12.269119989304315% use

5.1永久区差值:Perm2-Perm1=2701672 -2701672 =0

5.2堆区的差值:heap2-heap1=428528 -381192=47336

5.3保证采集到的对象个数是在无GC发生的情况下:

  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
  0.00   0.00  22.44   0.00  12.27      0    0.000     0    0.000    0.000
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
  0.00   0.00  20.18   0.00  12.27      0    0.000     0    0.000    0.000

5.4采集对象占用空间比较,由于内容较多,只选取差异的部分

 num     #instances         #bytes  class name

 204:             1             16               com.tt.st.jvm.Jvm

  15:          1000          16000          com.tt.st.jvm.Jvm

  14:           326          14208             [Ljava.lang.Object;

 12:           338            29152              [Ljava.lang.Object;

   6:          1354         128880              [C

   6:          1354         128888              [C

   8:            13            105880              [I

   7:            14          122280                  [I

sumbytes2-sumbytes1=47336

5.5、heap的差值=存活对象的差值

转载于:https://my.oschina.net/13426421702/blog/707661

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值