Java软引用 反射_从Java源码上复习反射的一些问题

Q:

用反射获取到的method对象, 是返回一个method引用,还是返回1个拷贝的method对象?

A:

反射拿method对象时, 会做一次拷贝,而不是直接返回引用,因此最好对频繁使用的同一个method做缓存,而不是每次都去查找。

d62339e361598362108415e01c3a20c5.png

Q:

getMethods()后自己做遍历获取方法

和getMethod(methodName) 直接获取方法, 为什么性能会有差异?

A:

getMethods() 返回method数组时,每个method都做了一次拷贝。

getMethod(methodName)只会返回那个方法的拷贝, 性能的差异就体现在拷贝上。

326e5c0656ec7de2a0ed42cbc5e6746e.png

Q:

获取方法时,jvm内部其实有缓存,但是返回给外部时依然会做拷贝。

那么该method的缓存是持久存在的吗?

A:

不是持久存在的,内存不足时会被回收。

源码如下:

908b6fcc560bf45f11ee71758df5e9a1.png

可以看到这是一个软引用。

软引用的定义:

内存紧张时可能会被回收,不过也可以通过-XX:SoftRefLRUPolicyMSPerMB参数控制回收的时机,

只要发生GC就会将其回收

如果reflectionData被回收之后,又执行了反射方法,那只能通过newReflectionData方法重新创建一个这样的对象了

Q: 反射是线程安全的吗?

A:

是线程安全的。 获取反射的数据时,通过cas去获取。

79401a301a040509732651fda3717d25.png

Q:

a普通方法调用

b反射方法调用

c关闭安全检查的反射方法调用,性能差异如下:

95196b026c14c4e1a3eb73ffb1cd9588.png

b反射方法调用和c关闭安全检查的反射方法调用的性能差异在哪?

普通方法调用和关闭安全检查的反射方法调用的性能差异在哪?

A:

安全检查的性能消耗在于

,SecurityManager.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION); 这项检测需要运行时申请 RuntimePermission(“accessDeclaredMembers”)。

所以如果不考虑安全检查, 对反射方法调用invoke时, 应当设置 Method#setAccessible(true)

普通方法和反射方法的性能差异在于

Method#invoke 方法会对参数做封装和解封操作

需要检查方法可见性

需要校验参数

反射方法难以内联

JIT 无法优化

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值