Jdk反射优化

使用 JDK 的动态代理时,会使用反射调用方法。但相比于正常调用方法,利用反射的性能要低一些,通过测试,我们可以看到Jdk内部对反射调用进行了优化。

如果jdk>=9的话,需添加下面的vm option参数。

复制代码
--add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/jdk.internal.reflect=ALL-UNNAMED

package com.example.demo2.b09;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class TestMethodInvoke {
    public static void main(String[] args) throws Exception {
        Method foo = TestMethodInvoke.class.getMethod("foo", int.class);

        for(int i = 1; i <= 17; i++){
            show(i, foo);
            foo.invoke(null, i);
        }
        System.in.read();
    }

    private static void show(int i, Method foo) throws Exception {
        Method getMethodAccessor = Method.class.getDeclaredMethod("getMethodAccessor");
        getMethodAccessor.setAccessible(true);
        Object invoke = getMethodAccessor.invoke(foo);
        if (invoke == null) {
            System.out.println(i + ":" + null);
            return;
        }
        // DelegatingMethodAccessorImpl 的全限定类名(不同版本的 JDK 存在差异)
        Field delegate = Class.forName("sun.reflect.DelegatingMethodAccessorImpl").getDeclaredField("delegate");
        delegate.setAccessible(true);
        System.out.println(i + ": " + delegate.get(invoke));
    }

    public static void foo(int i){
        System.out.println(i + ":" + "foo");
    }
}

输出结果:

复制代码
1: null
1: foo
2: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
2: foo
3: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
3: foo
4: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
4: foo
5: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
5: foo
6: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
6: foo
7: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
7: foo
8: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
8: foo
9: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
9: foo
10: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
10: foo
11: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
11: foo
12: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
12: foo
13: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
13: foo
14: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
14: foo
15: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
15: foo
16: sun.reflect.NativeMethodAccessorImpl@1be6f5c3
16: foo
17: sun.reflect.GeneratedMethodAccessor2@5b2133b1
17: foo

通过结果可以知道,前16次jdk使用的是本地的MethodAccessor实现反射调用,后面一次进行了优化,使用的是GeneratedMethodAccessor2进行调用,通过Arthas工具可以看到该类的实现,里面是正常调用foo方法,没有使用反射,提高了性能。

相关推荐
Turnsole_y7 小时前
pytest与Selenium结合使用指南
开发语言·python
wdfk_prog7 小时前
结合QBoot与HPatchLite实现高效差分升级(FOTA)
java·后端·struts
陈老师还在写代码8 小时前
android studio,java 语言。新建了项目,在哪儿设置 app 的名字和 logo。
android·java·android studio
消失的旧时光-19438 小时前
Kotlin reified泛型 和 Java 泛型 区别
java·kotlin·数据
郝学胜-神的一滴8 小时前
深入解析C++命令模式:设计原理与实际应用
开发语言·c++·程序人生·软件工程·命令模式
czhc11400756638 小时前
JAVA111 HashMap Leecode:1 两数之和 3 无重复字符串的长度
java
凌冰_8 小时前
Java Maven+lombok+MySql+HikariCP 操作数据库
java·数据库·maven
武子康8 小时前
Java-165 Neo4j 图论详解 欧拉路径与欧拉回路 10 分钟跑通:Python NetworkX 判定实战
java·数据库·性能优化·系统架构·nosql·neo4j·图论
ʚ希希ɞ ྀ8 小时前
单词接龙----图论
开发语言·javascript·ecmascript