记录一次压测中遇到的线程阻塞问题
java能够应用反射来执行办法调用,反射依据一个类名失去Class对象,再由对象名和给定的参数集拿到Method对象,就能够通过Method.invoke来执行

@CallerSensitive    public Object invoke(Object var1, Object... var2) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {        if(!this.override && !Reflection.quickCheckMemberAccess(this.clazz, this.modifiers)) {            Class var3 = Reflection.getCallerClass();            this.checkAccess(var3, this.clazz, var1, this.modifiers);        }        MethodAccessor var4 = this.methodAccessor;        if(var4 == null) {            var4 = this.acquireMethodAccessor();        }        return var4.invoke(var1, var2);    }

由下面的代码能够看进去invoke是由MethodAccessor来执行的,MethodAccessor又是acquireMethodAccessor办法获取到的

private MethodAccessor acquireMethodAccessor() {        MethodAccessor var1 = null;        if(this.root != null) {            var1 = this.root.getMethodAccessor();        }        if(var1 != null) {            this.methodAccessor = var1;        } else {            var1 = reflectionFactory.newMethodAccessor(this);             this.setMethodAccessor(var1);        }        return var1;    }

MethodAccessor是通过ReflectionFactory的newMethodAccessor获取的,代码如下:

 public MethodAccessor newMethodAccessor(Method var1) {        checkInitted();        if(noInflation && !ReflectUtil.isVMAnonymousClass(var1.getDeclaringClass())) {            return (new MethodAccessorGenerator()).generateMethod(var1.getDeclaringClass(), var1.getName(), var1.getParameterTypes(), var1.getReturnType(), var1.getExceptionTypes(), var1.getModifiers());        } else {            NativeMethodAccessorImpl var2 = new NativeMethodAccessorImpl(var1);            DelegatingMethodAccessorImpl var3 = new DelegatingMethodAccessorImpl(var2);            var2.setParent(var3);            return var3;        }    }

如果noInflation为true(不收缩,当Java虚拟机从JNI存取器改为字节码存取器的行为被称为收缩(Inflation)),创立MethodAccessorGenerator,否则NativeMethodAccessor。NativeMethodAccessorImpl中的invoke代码如下

public Object invoke(Object var1, Object[] var2) throws IllegalArgumentException, InvocationTargetException {        if(++this.numInvocations > ReflectionFactory.inflationThreshold() && !ReflectUtil.isVMAnonymousClass(this.method.getDeclaringClass())) {            MethodAccessorImpl var3 = (MethodAccessorImpl)(new MethodAccessorGenerator()).generateMethod(this.method.getDeclaringClass(), this.method.getName(), this.method.getParameterTypes(), this.method.getReturnType(), this.method.getExceptionTypes(), this.method.getModifiers());            this.parent.setDelegate(var3);//当这一步执行完之后,DelegatingMethodAccessorImpl中的delegate就是MethodAccessorImpl而不是NativeMethodAccessorImpl了        }        return invoke0(this.method, var1, var2);    }

ReflectionFactory.inflationThreshold() 就是jvm的启动参数的-Dsun.reflect.inflationThreshold,默认值是15.

调用次数没有超过这个阈值的时候其实应用的还是NativeMethodAccessor.invoke),即没有if外面那些解决。超出阈值后执行if中的逻辑,native的就被搞成了MethodAccessorImpl。同时setDelegate

这个setDelegate 要回看下面DelegatingMethodAccessorImpl,有点像一个中间层,在native和java版之间转换

class DelegatingMethodAccessorImpl extends MethodAccessorImpl {    private MethodAccessorImpl delegate;    DelegatingMethodAccessorImpl(MethodAccessorImpl var1) {        this.setDelegate(var1);    }    public Object invoke(Object var1, Object[] var2) throws IllegalArgumentException, InvocationTargetException {        return this.delegate.invoke(var1, var2);    }    void setDelegate(MethodAccessorImpl var1) {        this.delegate = var1;    }}

据说java版的启动慢,然而执行快(编译器能够优化);native版的启动快,然而执行慢。所以hotspot的jdk做了个优化,调用次数少时用native版的,当发现调用次数多时,则调用MethodAccessorGenerator.generateMethod()来生成Java版的MethodAccessor的实现类,并且扭转DelegatingMethodAccessorImpl所援用的MethodAccessor为Java版

sun.reflect.GeneratedMethodAccessor<N>是怎么呈现的呢?

默认这个优化是开启的且阈值是15,在后面多数调用时,调用的其实是native版的invoke0,超出阈值后,就开始应用MethodAccessorGenerator.generateMethod,这外面最终会调到一个genarateName办法

 private static synchronized String generateName(boolean var0, boolean var1) {        int var2;        if(var0) {            if(var1) {                var2 = ++serializationConstructorSymnum;                return "sun/reflect/GeneratedSerializationConstructorAccessor" + var2;            } else {                var2 = ++constructorSymnum;                return "sun/reflect/GeneratedConstructorAccessor" + var2;            }        } else {            var2 = ++methodSymnum;            return "sun/reflect/GeneratedMethodAccessor" + var2;        }    }