实际场景数据如下:
# 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时;
【温馨提示】
如果您觉得满意,可以选择支持下,您的支持是我最大的动力:
分享到:
相关推荐
2. 创建GroovyClassLoader:使用这个类加载器可以动态加载和执行Groovy脚本。它继承自Java的ClassLoader,能解析Groovy源码并生成字节码。 3. 加载并执行Groovy脚本:通过GroovyClassLoader的`parseClass()`方法...
### Groovy Script 入门知识点详解 #### 一、Groovy脚本简介 Groovy是一种灵活的面向对象的编程语言,它运行在Java平台上。由于其语法简洁且与Java高度兼容,因此对于Java开发者来说非常容易上手。Groovy不仅支持...
groovy-loader load groovy scripts in file directory dynamically ...spring配置文件使用标签lang:groovy,通过指定script-source来加载指定路径下的groovy脚本,通过refresh-check-delay属性来定时
2. **方法2:反射动态调用** - 使用Java的反射机制,可以在运行时动态加载和执行Groovy类。这种方法的优点是Groovy脚本的修改不需要重新编译整个项目,因为Java代码可以通过反射动态地找到并调用Groovy方法。这里,...
元编程在Groovy中主要通过`MetaClass`接口和`ExpandoMetaClass`类来实现。 `MetaClass`是Groovy中的一个核心概念,它是每个Groovy对象的元数据容器,存储了对象的方法、属性以及它们的调用规则。通过`MetaClass`,...
9. **类和对象**:虽然文件名没有直接体现,但在Groovy中,你可以创建类和对象,支持面向对象编程,包括继承、封装和多态。 通过学习和实践这些文件中的代码,Groovy初学者可以逐步掌握Groovy语言的基础和一些高级...
通过创建一个GroovyShell实例,我们可以传递一个类加载器和一个绑定对象,然后使用`evaluate()`方法执行Groovy代码。例如: ```java import groovy.lang.GroovyShell; import groovy.lang.Binding; public class ...
groovy-loader-v2 load groovy scripts in file directory dynamically 简介 ...通过GroovyScriptFactory一级类加载器来实例化groovy脚本 通过扫描监听指定路径下groovy文件的变更,来接受groovy脚本的
Groovy是一种强大的、动态的编程语言,它无缝集成在Java平台上,使得开发人员可以利用其简洁的语法和灵活性来提高生产力。在Java生态系统中,Groovy经常被用来处理XML文档,因为它的动态特性使得XML的读取、修改和...
本文将详细讲解如何使用JVM动态执行Groovy脚本的方法,主要包括利用JShell执行代码、调试模式下动态执行代码以及利用javax.script包执行Groovy脚本。以下是对各知识点的详细说明。 1. 利用JShell执行代码 Java 9 ...
Groovy MOP,全称Meta-Object Protocol(元对象协议),是Groovy语言的一个核心特性,它提供了一种强大的方式来扩展和修改类的行为。在Java中,我们通常需要通过继承或接口实现来扩展功能,但Groovy的MOP允许我们在...
Groovy是一种基于Java平台的动态脚本语言,它在Java开发者中越来越受欢迎,因为它提供了简洁、灵活的语法,以及强大的动态编程能力。Groovy与Java兼容性极佳,可以直接调用Java类库,使得它在Java生态系统中具有广泛...
Groovy是一种基于Java平台的动态编程语言,设计用于提高开发者的生产力和代码的简洁性。在Java生态系统中,Groovy以其灵活性和与Java的良好互操作性而受到广泛关注。本篇文章将深入探讨Groovy的最新学习动态,特别是...
在Java开发中,Groovy是一种强大的、动态类型的脚本语言,它可以无缝地与Java代码集成,为开发者提供了更简洁、灵活的语法。本文将深入探讨在Java项目中使用Groovy的三种主要方式,并阐述它们各自的优势和应用场景。...
自创Groovy DSL 动态规则(rule)执行引擎, 流程引擎. 特色 风控系统, 规则引擎, 动态接口配置(低代码)Groovy DSL 动态规则(rule)执行引擎。DSL(特定领域语言): 开发 和 业务 共识的语言。方便业务表达需求, 方便开发...
JUN SpringBoot API Service 是一个基于SpringBoot+Groovy+SQL动态生成API并动态发布,且发布后可动态执行groovy脚本及SQL脚本的API服务项目。提供在线执行动态程序脚热加载本及动态生成API并执行的功能。支持动态...
GroovyShell允许在运行时执行Groovy脚本,而GroovyClassLoader则可以动态加载和执行新的类。在Java应用中,只需几行代码,就可以实现Groovy脚本的编译和执行: ```java GroovyShell shell = new GroovyShell(); ...
本文将深入探讨如何在Spring Boot项目中集成Groovy,并通过两种方式实现动态执行:通过Groovy文件执行脚本和通过数据库动态执行。 首先,让我们了解Groovy如何与Spring Boot结合。Spring Boot提供了对Groovy的支持...
Java调用Groovy是一种常见的技术,特别是在开发过程中需要动态脚本支持时...通过`GroovyShell`、`GroovyScriptEngine`以及动态加载和执行Groovy类,Java开发者可以充分利用Groovy的优势,提升项目的可扩展性和维护性。
* 动态语言特性,支持动态类类型转换、闭包和元编程等功能。 * 面向对象编程语言,支持面向对象编程和纯粹的脚本语言使用。 * 与 Java 代码的无缝集成,可以与 Java 代码混合使用。 * 专门为 JVM 设计,设计时充分...