类是不是也要保存在内存中?

来源:2-3 jstat查看JVM统计信息

birdskyws

2018-12-02

class A{
String name;
Static B b =new B();
}
class B{
String name;
}
第一个问题:
CCS保存指向类的指针,那么哪部分内存保存了类?
第二个问题:
静态成员变量,new B()是被分配到堆中,还是metaspace中?
图片描述

写回答

3回答

若鱼1919

2018-12-04

Controller源码:

定义100个int数组:

private static int[] arr1 = new int[1023*1023];

private static int[] arr2 = new int[1023*1023];

private static int[] arr99 = new int[1023*1023];


启动参数:

java -Xmx2048M -Xms2048M -XX:MetaspaceSize=64M -XX:+UseG1GC -XX:G1HeapRegionSize=8 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:gc.log -jar target/monitor_tuning.war


gc日志截取:


Java HotSpot(TM) 64-Bit Server VM (25.144-b01) for windows-amd64 JRE (1.8.0_144-b01), built on Jul 21 2017 21:57:33 by "java_re" with MS VC++ 10.0 (VS2010)

Memory: 4k page, physical 8240044k(4379448k free), swap 10730412k(6230732k free)

CommandLine flags: -XX:G1HeapRegionSize=8 -XX:InitialHeapSize=2147483648 -XX:MaxHeapSize=2147483648 -XX:MetaspaceSize=67108864 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation 


第一次GC:Eden区从102M变为0,Survivors区从0变为8M, 整个堆从102变为8M,也就是说Eden区有8M没有被回收掉,放到了Survivors

2018-12-04T09:35:42.444+0800: 1.577: [GC pause (G1 Evacuation Pause) (young), 0.0096806 secs]

   [Eden: 102.0M(102.0M)->0.0B(94.0M) Survivors: 0.0B->8192.0K Heap: 102.0M(2048.0M)->7699.0K(2048.0M)]


第二次GC:Eden区从94M变为0,Survivors从8M变为9M,整个堆从101M变为9M,说明Eden区有1M没有被回收掉,放到了Survivors

2018-12-04T09:35:43.429+0800: 2.560: [GC pause (G1 Evacuation Pause) (young), 0.0130069 secs]

   [Eden: 94.0M(94.0M)->0.0B(109.0M) Survivors: 8192.0K->9216.0K Heap: 101.5M(2048.0M)->9216.0K(2048.0M)]


第三次GC:Eden区从109M变为0,Survivors从9M变为12M,整个堆从118M变为12M,说明Eden区有3M没有被回收掉,放到了Survivors

2018-12-04T09:35:44.863+0800: 3.996: [GC pause (G1 Evacuation Pause) (young), 0.0155580 secs]

   [Eden: 109.0M(109.0M)->0.0B(200.0M) Survivors: 9216.0K->12.0M Heap: 118.0M(2048.0M)->12.0M(2048.0M)]

 [Times: user=0.05 sys=0.01, real=0.02 secs] 


第四次GC:Eden区从200M变为0,Survivors从12M变为21M,整个堆从608M变为415M,说明有(415-21 = 394)394M晋升到了old区

2018-12-04T09:35:47.010+0800: 6.132: [GC pause (G1 Evacuation Pause) (young), 0.0229256 secs]

   [Eden: 200.0M(200.0M)->0.0B(364.0M) Survivors: 12.0M->21.0M Heap: 607.2M(2048.0M)->415.7M(2048.0M)]

Heap

 garbage-first heap   total 2097152K, used 507626K [0x0000000080000000, 0x0000000080104000, 0x0000000100000000)

  region size 1024K, 102 young (104448K), 21 survivors (21504K)

 Metaspace       used 30109K, capacity 30626K, committed 30720K, reserved 1077248K

  class space    used 3694K, capacity 3805K, committed 3840K, reserved 1048576K


说明这些对象一开始是在young区的Eden区分配的,最终晋升到了old区。


0
1
birdskyws
好的,谢谢老师
2018-12-04
共1条回复

若鱼1919

2018-12-03

对象总是在eden区分配的,除了那种超大对象

0
0

若鱼1919

2018-12-03

(1)Class字节码是分配在metaspace的

(2)new B(), B这个对象一开始是在eden区分配的

0
1
birdskyws
Static Class b = new B(),也是分配在eden区吗,那么这些变量应该不需要释放吧,肯定会晋升到老年代。但是在每次GC的时候,都需要扫描这些对象,这样不是白白做了很多工作?
2018-12-03
共1条回复

Java生产环境下性能监控与调优详解

系统掌握线上性能监控与 GC调优,线上代码调试

2373 学习 · 262 问题

查看课程