使用火焰图分析org.apache.commons.beanutils.BeanUtils

一、Java Flight Recorder

参考:https://blog.csdn.net/qq_37552993/article/details/102545780
配置之后让测试程序运行五分钟,得到下面这张图
ps:所copy的对象只有俩字段
在这里插入图片描述

二、分析耗时原因

2.1 isReadable isWriteable

每次copy时会对每个字段的可读性和可写性进行重复判断,而由于在复制过程中类的结构一般不会改变,所以这俩状态应该被缓存下来。

结论来源:https://blog.csdn.net/u010209217/article/details/84837821

通过反射方式获取可读性和可写性

isPackageAccessible:195, ReflectUtil (sun.reflect.misc)
get:71, MethodRef (java.beans)
getReadMethod:207, PropertyDescriptor (java.beans)
getReadMethod:1256, PropertyUtilsBean (org.apache.commons.beanutils)
isReadable:1435, PropertyUtilsBean (org.apache.commons.beanutils)
copyProperties:281, BeanUtilsBean (org.apache.commons.beanutils)
copyProperties:137, BeanUtils (org.apache.commons.beanutils)
copyProperties:8, CommonsBeanUtilsPropertiesCopier (com.test.BeanutilsTest.copier.Impl)
CommonsBeanUtilsPropertiesCopierTest:25, CopierShowError (com.test.BeanutilsTest)
main:38, CopierShowError (com.test.BeanutilsTest)
isPackageAccessible:195, ReflectUtil (sun.reflect.misc)
getBeanInfo:164, Introspector (java.beans)
getPropertyDescriptors:980, PropertyUtilsBean (org.apache.commons.beanutils)
getPropertyDescriptors:1084, PropertyUtilsBean (org.apache.commons.beanutils)
getPropertyDescriptor:912, PropertyUtilsBean (org.apache.commons.beanutils)
isWriteable:1523, PropertyUtilsBean (org.apache.commons.beanutils)
copyProperties:281, BeanUtilsBean (org.apache.commons.beanutils)
copyProperties:137, BeanUtils (org.apache.commons.beanutils)
copyProperties:8, CommonsBeanUtilsPropertiesCopier (com.test.BeanutilsTest.copier.Impl)
CommonsBeanUtilsPropertiesCopierTest:25, CopierShowError (com.test.BeanutilsTest)
main:38, CopierShowError (com.test.BeanutilsTest)

2.2 StringBuffer.append

输出了大量的日志调试信息

结论来源:https://segmentfault.com/a/1190000019356477

append:262, StringBuffer (java.lang)
convert:1077, BeanUtilsBean (org.apache.commons.beanutils)
copyProperty:437, BeanUtilsBean (org.apache.commons.beanutils)
copyProperties:286, BeanUtilsBean (org.apache.commons.beanutils)
copyProperties:137, BeanUtils (org.apache.commons.beanutils)
copyProperties:8, CommonsBeanUtilsPropertiesCopier (com.test.BeanutilsTest.copier.Impl)
CommonsBeanUtilsPropertiesCopierTest:25, CopierShowError (com.test.BeanutilsTest)
main:38, CopierShowError (com.test.BeanutilsTest)

2.3、getSimpleProperty

与isReadable类似,此函数内调用了getReadMethod以获取读方法,在getReadMethod又进一步调用反射方法,所以性能低。

isPackageAccessible:195, ReflectUtil (sun.reflect.misc)
get:71, MethodRef (java.beans)
getReadMethod:207, PropertyDescriptor (java.beans)
getReadMethod:1256, PropertyUtilsBean (org.apache.commons.beanutils)
getSimpleProperty:1325, PropertyUtilsBean (org.apache.commons.beanutils)
copyProperties:284, BeanUtilsBean (org.apache.commons.beanutils)
copyProperties:137, BeanUtils (org.apache.commons.beanutils)
copyProperties:8, CommonsBeanUtilsPropertiesCopier (com.test.BeanutilsTest.copier.Impl)
CommonsBeanUtilsPropertiesCopierTest:25, CopierShowError (com.test.BeanutilsTest)
main:38, CopierShowError (com.test.BeanutilsTest)

这个函数中获取的读方法实际上已存在于descriptorsCache这个缓存中,但是需要通过反射进一步校验访问权限

在这里插入图片描述校验访问权限。

    Method get() {
        if (this.methodRef == null) {
            return null;
        }
        Method method = this.methodRef.get();
        if (method == null) {
            method = find(this.typeRef.get(), this.signature);
            if (method == null) {
                this.signature = null;
                this.methodRef = null;
                this.typeRef = null;
                return null;
            }
            this.methodRef = new SoftReference<>(method);
        }
        return isPackageAccessible(method.getDeclaringClass()) ? method : null;// 若有权限,返回方法,反之返回null
    }

三、总结

通过火焰图发现StringBuffer.append isReadable isWriteable getSimpleProperty调用时间长,进一步分析发现,耗时问题可以被分为两类,一类是字符串拼接,一类是反射方法isPackageAccessible的调用。

除了上述方法之外,还有很多其他方法也调用了isPackageAccessible
在这里插入图片描述

end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值