• 为什么反射慢?


    反射机制就是通过字节码文件对象获取成员变量、成员方法和构造方法,然后进一步获取它们的具体信息,如名字、修饰符、类型等。

    反射机制的性能较低有很多原因,这里详细总结以下4点原因:

    (1)JIT优化受限:
    JIT 编译器的优化是基于静态分析和预测的。反射是一种在运行时动态解析类型信息的机制,在编译时无法确定反射调用的具体方法,因此编译器无法对这些代码进行静态分析,从而无法进行一些JIT优化,比如:

    内联优化受限:JIT 编译器通常会对频繁调用的方法进行内联优化,将方法调用替换为直接的代码。但是,由于反射调用的方法在运行时才能确定,因此 JIT 编译器无法进行有效的内联优化。

    无法进行即时编译:因为反射调用的方法在运行时才能确定,因此在解释执行阶段,我们无法确定反射调用的方法会被执行多少次,会不会成为热点代码,也就无法对其进行即时编译优化。

    (2)反射中频繁的自动拆装箱操作会导致应用性能下降:
    在反射中,当你调用一个方法时,由于在编译时不知道具体要调用的方法参数类型,因此需要用最通用的引用类型来处理所有的参数,即Object。例如,通过Method对象调用方法时,使用的invoke方法签名大致如下:

    public Object invoke(Object obj, Object... args)
    

    对于基本数据类型的参数,它们必须被装箱成对应的包装类(如IntegerDouble等),以便它们可以作为对象被传递。在方法实际执行时,如果方法的参数是基本类型,JVM需要基本类型的值,而不是它们的包装类对象。因此,JVM会自动进行拆箱。例如,如果你通过反射调用的方法期望得到一个int类型的参数,但你传入的是Integer,在调用过程中JVM会自动将Integer对象拆箱为int类型。装箱和拆箱操作涉及到额外的对象创建(装箱时)和对象值的提取(拆箱时),在高性能要求的场景下,过度的装箱和拆箱可能会导致性能瓶颈。此外,由于装箱操作导致创建了许多短生命周期的对象,这些对象在成为垃圾后,需要通过垃圾回收过程来回收内存资源,当有大量对象需要回收时,GC会占用更多的CPU资源,可能导致应用性能暂时下降。

    (3)遍历操作
    反射在调用方法时会从方法数组中遍历查找,这对普通的方法调用来说是不需要的。

    (4)方法访问检查
    每次使用反射调用方法时,JVM都要检查是否允许访问该方法,例如是否为私有方法等。这些访问检查对普通的方法调用来说是不需要的,因为这些检查都是在编译时完成的。


    __EOF__

  • 本文作者: 北冥有鱼
  • 本文链接: https://www.cnblogs.com/hashcodee/p/18310857
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    十天学完基础数据结构-第二天(数据结构简介)
    Spring Boot集成Redis实现数据缓存
    梯度下降——机器学习
    软件工程毕业设计课题(60)微信小程序毕业设计JAVA共享充电桩小程序系统设计与实现
    【Unity之竖屏游戏制作】如何做一个竖屏的手机游戏
    Oracle实现主键字段自增
    APP自动化之weditor工具
    【教3妹学算法-每日3题(2)】去掉最低工资和最高工资后的工资平均值
    【Exploit trick】利用poll_list对象构造kmalloc-32任意释放 (corCTF 2022-CoRJail)
    GNSS+IMU学习
  • 原文地址:https://www.cnblogs.com/hashcodee/p/18310857