feat: reflect analysis
purpose
Added reflection analysis function to analyze all the methods corresponding to sun.reflect.GeneratedMethodAccessor to assist in troubleshooting insufficient metaspace problem.
usage
1.reflect-analysis 2.reflect-analysis reflect-analysis-result.csv
When it is a relative path, the file will be generated in a temporary directory.
Example
count,refName,names
3,org.springframework.boot.admin.SpringApplicationAdminMXBean#getProperty,GeneratedMethodAccessor23,GeneratedMethodAccessor22,GeneratedMethodAccessor24
2,javax.management.remote.rmi.RMIConnection#invoke,GeneratedMethodAccessor20,GeneratedMethodAccessor21
1,cn.ares.boot.demo.user.request.UserRequest#getId,GeneratedMethodAccessor1
1,com.sun.management.OperatingSystemMXBean#getProcessCpuLoad,GeneratedMethodAccessor40
1,javax.management.ObjectName#readObject,GeneratedMethodAccessor4
1,javax.management.remote.rmi.RMIConnection#close,GeneratedMethodAccessor25
1,javax.management.remote.rmi.RMIConnection#getAttribute,GeneratedMethodAccessor8
1,javax.management.remote.rmi.RMIConnection#getConnectionId,GeneratedMethodAccessor15
1,javax.management.remote.rmi.RMIServer#newClient,GeneratedMethodAccessor14
1,org.springframework.boot.actuate.env.EnvironmentEndpoint$PropertyValueDescriptor#getOrigin,GeneratedMethodAccessor28
1,org.springframework.boot.actuate.env.EnvironmentEndpoint$PropertyValueDescriptor#getOriginParents,GeneratedMethodAccessor29
1,org.springframework.boot.actuate.env.EnvironmentEndpoint$PropertyValueDescriptor#getValue,GeneratedMethodAccessor27
1,org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletMappingDescription#getDetails,GeneratedMethodAccessor33
1,org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletMappingDescription#getHandler,GeneratedMethodAccessor31
1,org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletMappingDescription#getPredicate,GeneratedMethodAccessor32
@hengyunabc PTAL
麻烦解析下原理,怎么工作的,解决哪些问题。
麻烦解析下原理,怎么工作的,解决哪些问题。
解决的问题
在某些情况下(比如动态加载类后未正确卸载)会不断地产生sun.reflect.GeneratedMethodAccessor对象导致元空间(通过JVM参数限定了大小)不足,从而不断地触发FullGc导致服务不稳定甚至不可用,此时需要知道大量的sun.reflect.GeneratedMethodAccessor所对应的方法才能知道问题出在哪里。
原理
1.查找当前JVM中所有的sun.reflect.GeneratedMethodAccessor类; 2.遍历这些类使用asm分析出它们所对应的方法,一个sun.reflect.GeneratedMethodAccessor的示例:
package sun.reflect;
import cn.ares.boot.demo.user.request.UserRequest;
import java.lang.reflect.InvocationTargetException;
import sun.reflect.MethodAccessorImpl;
public class GeneratedMethodAccessor1
extends MethodAccessorImpl {
/*
* Loose catch block
*/
public Object invoke(Object object, Object[] objectArray) throws InvocationTargetException {
UserRequest userRequest;
block5: {
if (object == null) {
throw new NullPointerException();
}
userRequest = (UserRequest)object;
if (objectArray == null || objectArray.length == 0) break block5;
throw new IllegalArgumentException();
}
try {
return userRequest.getId();
}
catch (Throwable throwable) {
throw new InvocationTargetException(throwable);
}
catch (ClassCastException | NullPointerException runtimeException) {
throw new IllegalArgumentException(super.toString());
}
}
}
3.根据类+方法名作统计计数; 4.将结果输出至终端或文件;
@hengyunabc PTAL
感觉是一个非常小众的场景,直接 heapdump 应该也可以分析出来。 或者直接用 classloader 命令来查看有哪些 classloader,再看它们加载的类列表。
感觉是一个非常小众的场景,直接 heapdump 应该也可以分析出来。 或者直接用 classloader 命令来查看有哪些 classloader,再看它们加载的类列表。
确实是一个偏小众的需求,但通过classloader查看只能查看到sun.reflect.GeneratedMethodAccessor这一层,sun.reflect.GeneratedMethodAccessor背后所对应的方法是无法统计的,heapdump是可以分析出来的但这个过程也并不是很简单,Arthas是否有计划实现一个插件机制将一些非核心的指令迁移过去并更方便用户自己扩展与贡献。