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方法,没有使用反射,提高了性能。

相关推荐
小则又沐风a2 分钟前
STL库: string类
开发语言·c++
菜菜小狗的学习笔记3 分钟前
八股(二)Java集合
java·开发语言
星乐a4 分钟前
String 不可变性与常量池深度解析
java·开发语言
captain3765 分钟前
ACM模式下Java输入输出函数为什么会超时?及解决方法
java·开发语言
程序员老邢10 分钟前
【产品底稿 04】商助慧 V1.1 里程碑:爬虫入库 + MySQL + Milvus 全链路打通
java·爬虫·mysql·ai·springboot·milvus
2601_9507039412 分钟前
Java安全编程与静态分析实战
java
唐叔在学习13 分钟前
Python移动端应用消息提醒开发实践
开发语言·python
好家伙VCC13 分钟前
**发散创新:基于Python与OpenCV的视频流帧级分析实战**在当前人工智能与计算机视觉飞速发展的背景下
java·人工智能·python·计算机视觉
SimonKing14 分钟前
大V说’AI替代不了你’,但现实是——用AI的人正在替代你
java·后端·程序员
暴力求解14 分钟前
C++ ---string类(三)
开发语言·c++