反射调用

反射:
    在程序运行时,另一种方式的调用构造方法,方法,字段的行为。应用在框架,java集成开发环境idea中。
    
    方法反射调用的实现:
        method实例指向方法的地址值(类加载到虚拟机中,方法会加载到方法区,有明确的地址),反射调用传入准备好的参数,调用进入目标方法。
        每次调用invoke,都会通过一个委派实现调用本地方法实现反射调用。当调用达到一定的次数(15次)之后,就会动态生成字节码实现(相当于生成了一个类),下次调用的时候,委派实现就会调用这个动态实现去完成方法的调用。
        本地方法实现和动态实现的切换过程叫做inflation。可通过参数-Dsun.reflect.noInflation=true进行开启与关闭
        
    反射调用的开销
            class.forName调用本地方法
            占用堆内存,是的GC频繁。(invoke()是个变长参数方法Obeject数组,每次都要生成新的数组。)
                即时编译优化方法内联:反射调用被内联了,即时编译的逃逸分析将新建的Objec数组判定为不会逃逸对象,因此不会触发垃圾回收。假设invoke()方法外创建数组,无法优化访问数组的操作。
            
            基本数组类型拆箱装箱(Objec数组,基本类型要拆箱装箱)
                java缓存了-128到127,还可手动调整缓存范围
                
            本地方法实现消耗性能
                关闭反射调用inflation机制。
            
            方法多个有不同的动态实现,可能会造成方法内联的失效,逃逸分析不再起作用。
                生产环境有多个不同的动态实现,对于 invokevirtual 或者 invokeinterface,Java 虚拟机会记录下调用者的具体类型(称之为类型 profile),java虚拟机无法同时记录这么多类,可能会造成方法内联失效,逃逸分析不再起效
                
    方法内联:指的是编译器在编译一个方法时,将某个方法调用的目标方法也纳入编译范围内,并用其返回值替代原方法调用这么个过程

posted @ 2020-09-14 10:07  小__七  阅读(504)  评论(0)    收藏  举报