`
can_do
  • 浏览: 248752 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【Do家】通过Groovy动态加载Script类对象分析class object GC和unloaded Class关系

阅读更多
实际场景数据如下:
# jstat -gccause 73 3000 10
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC                
20.38   0.00  84.24  40.49  94.09  89.96   1274   56.063     0    0.000   56.063 Allocation Failure   No GC              

jvm未发生过FGC;
# jstat -class 73
Loaded  Bytes  Unloaded  Bytes     Time  
22893 42938.7        0     0.0      21.78

未出现类卸载(unloaded);
# jmap -histo 73 > jmap_histo_in_manual_0728_1.txt
# grep '24  Script' ./jmap_histo_in_manual_0728_1.txt
6289:             1             24  Script13
6290:             1             24  Script6
6291:             1             24  Script62
6292:             1             24  Script65
6293:             1             24  Script68
# grep 'GroovyClassLoader' ./jmap_histo_in_manual_0728_1.txt
439:           200          25600  groovy.lang.GroovyClassLoader$InnerLoader
1025:           201           3216  groovy.lang.GroovyClassLoader$1
3410:             1            112  groovy.lang.GroovyClassLoader
**********************************************
$ classloader
name                                                      numberOfInstances  loadedCountTotal                                            
org.apache.catalina.loader.ParallelWebappClassLoader      1                  13815                                                       
BootstrapClassLoader                                      1                  4142                                                        
com.yonyou.cloud.iceberg.LaunchedURLClassLoader           1                  3422                                                        
sun.reflect.DelegatingClassLoader                         1636               1636                                                        
com.taobao.arthas.agent.ArthasClassloader                 1                  1200                                                        
java.net.URLClassLoader                                   1                  768                                                         
sun.misc.Launcher$AppClassLoader                          1                  373                                                         
groovy.lang.GroovyClassLoader$InnerLoader                 200                200                                                         
com.yonyou.cloud.iceberg.HessianClassLoader               1                  93                                                          
org.codehaus.groovy.runtime.callsite.CallSiteClassLoader  25                 45                                                          
sun.misc.Launcher$ExtClassLoader                          1                  43                                                          
com.alibaba.fastjson.util.ASMClassLoader                  2                  19                                                          
org.codehaus.groovy.reflection.SunClassLoader             1                  1                                                           
groovy.lang.GroovyClassLoader                             1                  0                                                           
Affect(row-cnt:14) cost in 50 ms.
************************************

# jmap -histo:live 73 > jmap_histo_in_manual_0728_2.txt
相当手动触发1次FGC
# jstat -gccause 73 3000 10
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC                
  0.00   0.00   5.94  32.46  94.04  89.74   1285   56.613     1    3.085   59.698 Heap Inspection Initiated GC No GC              
# jstat -class 73
Loaded  Bytes  Unloaded  Bytes     Time  
24149 45240.2      163   229.5      22.36
经过FGC后,开始出现类的元数据被unloaded掉了;

【分析】
通过arthas和jstat,可以看到groovy.lang.GroovyClassLoader$InnerLoader为200个,并且加载的类也是200个,此处加载的类就是Script<Number>,由Groovy运行期动态解析Script得到的类;
已知:Groovy动态加载Script类时,按每个Script对一个ClassLoader,即groovy.lang.GroovyClassLoader$InnerLoader,每加载一个Script<Number>,同时也生成一个GroovyClassLoader.InnerLoader类对象;

按此线索,java中Script<Number>类对象应该是200个,但是通过jmap -histo发现,该Script<Number>类对象仅5个,如下:
///////////begin////////
# grep '24  Script' ./jmap_histo_in_manual_0728_1.txt
6289:             1             24  Script13
6290:             1             24  Script6
6291:             1             24  Script62
6292:             1             24  Script65
6293:             1             24  Script68
//////////end////////////
说明:曾经解析得到的200个Script<Number>类对象,已被大部分回收,仅剩下5个了;

另一方面,通过jstat也发现在没有unloadded的类情况,heap中类对象已被回收了,

由此,得到结论:

1> heap中类对象是否被回收,仅与其引用有关,与该类对象的类元数据或者其classloader是否被卸载无关;

2> 相反,class是否被unloaded掉,是发生在类对象被GC之后的,即类对象被GC后,其相应的类元数据会被unloaded掉;

3> class被unloaded时机,发生在FGC时;

【温馨提示】
如果您觉得满意,可以选择支持下,您的支持是我最大的动力:

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics