包含javareflectutils的词条

今天给各位分享javareflectutils的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

1、Java程序性能优化-代理模式(5)2、实验: metaspace区域OOM3、Bean找对象方法执行4、后端自定义的异常 在dubbo 怎么抛到前端

Java程序性能优化-代理模式(5)

  代理模式( )

在以上代码中 使用CtField make()方法和CtNewMehod make()方法在运行时生成了代理类的字段和方法 这些逻辑由Javassist的CtClass对象处理 将Java代码转换为对应的字节码 并生成动态代理类的实例

注意 与静态代理相比 动态代理可以很大幅度地减少代码行数 并提升系统的灵活性

在Java中 动态代理类的生成主要涉及对ClassLoader的使用 这里以CGLIB为例 简要阐述动态类的加载过程 使用CGLIB生成动态代理 首先需要生成Enhancer类实例 并指定用于处理代理业务的回调类 在Enhancer create()方法中 会使用DefaultGeneratorStrategy Generate()方法生成动态代理类的字节码 并保存在byte数组中 接着使用ReflectUtils defineClass()方法 通过反射 调用ClassLoader defineClass()方法 将字节码装载到ClassLoader中 完成类的加载 最后使用ReflectUtils newInstance()方法 通过反射 生成动态类的实例 并返回该实例 无论使用何种方法生成动态代理 虽然实现细节不同 但主要逻辑都如图 所示

图   实现动态代理的基本步骤

前文介绍的几种动态代理的生成方法 性能有一定差异 为了能更好地测试它们的性能 去掉DBQuery类中的sleep()代码 并使用以下方法测试

public static final int CIRCLE= ;

public static void main(String[] args) throws Exception {

IDBQuery d=null;

long begin=System currentTimeMillis()

d=createJdkProxy()                      //测试JDK动态代理

System out println( createJdkProxy: +(System currentTimeMillis() beg    in))

System out println( JdkProxy class: +d getClass() getName())

begin=System currentTimeMillis()

for(int i= ;iCIRCLE;i++)

d request()

System out println( callJdkProxy: +(System currentTimeMillis() begin    ))

begin=System currentTimeMillis()

d=createCglibProxy()                    //测试CGLIB动态代理

System out println( createCglibProxy: +(System currentTimeMillis() b    egin))

System out println( CglibProxy class: +d getClass() getName())

begin=System currentTimeMillis()

for(int i= ;iCIRCLE;i++)

d request()

System out println( callCglibProxy: +(System currentTimeMillis() beg    in))

begin=System currentTimeMillis()

d=createJavassistDynProxy()             //测试Javaassist动态代理

System out println( createJavassistDynProxy: +(System currentTimeMil    lis() begin))

System out println( JavassistDynProxy class: +d getClass() getName())

begin=System currentTimeMillis()

for(int i= ;iCIRCLE;i++)

d request()

System out println( callJavassistDynProxy: +(System currentTimeMilli    s() begin))

begin=System currentTimeMillis()

d=createJavassistBytecodeDynamicProxy()     //测试Javassist动态代理

System out println( createJavassistBytecodeDynamicProxy: +(System cu    rrentTimeMillis() begin))

System out println( JavassistBytecodeDynamicProxy class: +d getClass()

getName())

begin=System currentTimeMillis()

for(int i= ;iCIRCLE;i++)

d request()

System out println( callJavassistBytecodeDynamicProxy: +(System curr    entTimeMillis() begin))

}

       返回目录 Java程序性能优化 让你的Java程序更快 更稳定

编辑推荐

       Java程序设计培训视频教程

       J EE高级框架实战培训视频教程

       J ME移动开发实战教学视频

Visual C++音频/视频技术开发与实战

Oracle索引技术

lishixinzhi/Article/program/Java/gj/201311/27830

实验: metaspace区域OOM

Cglib 动态代理,会动态创建类 如果使用不当会导致生成大量的类元数据 塞满metaspace

依赖包

执行报错

java.lang.OutOfMemoryError: Metaspace

Dumping heap to ./\java_pid13748.hprof …

Heap dump file created [2923143 bytes in 0.037 secs]

Exception in thread “main” net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException–null

at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:348)

at net.sf.cglib.proxy.Enhancer.generate(Enhancer.java:492)

at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:117)

at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:294)

at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:480)

at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:305)

at MetaspaceOOM.main(MetaspaceOOM.java:42)

Caused by: java.lang.reflect.InvocationTargetException

at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:459)

at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:339)

… 6 more

Caused by: java.lang.OutOfMemoryError: Metaspace

at java.lang.ClassLoader.defineClass1(Native Method)

at java.lang.ClassLoader.defineClass(ClassLoader.java:763)

… 11 more

4.669: [GC (Allocation Failure) 4.669: [ParNew: 34944K-2104K(39296K), 0.0033046 secs] 34944K-2104K(126720K), 0.0035844 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

5.218: [GC (Allocation Failure) 5.218: [ParNew: 37048K-2256K(39296K), 0.0051226 secs] 37048K-2256K(126720K), 0.0053311 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

5.633: [GC (Allocation Failure) 5.633: [ParNew: 37200K-2664K(39296K), 0.0101116 secs] 37200K-2664K(126720K), 0.0102989 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

Gc日志还是比较清晰的打印出 Metadata 到达阈值引起的fullgc

5.973: [ Full GC (Metadata GC Threshold) 5.973: [CMS: 0K-2302K(87424K), 0.0538876 secs] 28792K-2302K(126720K), [Metaspace: 9186K-9186K(1058816K)], 0.0543441 secs] [Times: user=0.08 sys=0.03, real=0.06 secs]

6.027: [Full GC (Last ditch collection) 6.027: [CMS: 2302K-1410K(87424K), 0.0168118 secs] 2302K-1410K(126848K), [Metaspace: 9186K-9186K(1058816K)], 0.0169643 secs] [Times: user=0.03 sys=0.00, real=0.02 secs]

6.046: [GC (CMS Initial Mark) [1 CMS-initial-mark: 1410K(87424K)] 1410K(126848K), 0.0003738 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

6.046: [CMS-concurrent-mark-start]

6.089: [CMS-concurrent-mark: 0.014/0.043 secs] [Times: user=0.06 sys=0.00, real=0.04 secs]

6.089: [CMS-concurrent-preclean-start]

6.091: [CMS-concurrent-preclean: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

6.091: [GC (CMS Final Remark) [YG occupancy: 687 K (39424 K)]6.091: [Rescan (parallel) , 0.0003632 secs]6.091: [weak refs processing, 0.0001684 secs]6.091: [class unloading, 0.0022085 secs]6.094: [scrub symbol table, 0.0013801 secs]6.095: [scrub string table, 0.0003217 secs][1 CMS-remark: 1410K(87424K)] 2097K(126848K), 0.0048304 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

6.096: [CMS-concurrent-sweep-start]

6.096: [CMS-concurrent-sweep: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

6.097: [CMS-concurrent-reset-start]

6.099: [CMS-concurrent-reset: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

par new generation total 39424K, used 1038K [0x0000000081200000, 0x0000000083cc0000, 0x0000000095ec0000)

eden space 35072K, 2% used [0x0000000081200000, 0x0000000081303890, 0x0000000083440000)

from space 4352K, 0% used [0x0000000083440000, 0x0000000083440000, 0x0000000083880000)

to space 4352K, 0% used [0x0000000083880000, 0x0000000083880000, 0x0000000083cc0000)

concurrent mark-sweep generation total 87424K, used 1410K [0x0000000095ec0000, 0x000000009b420000, 0x0000000100000000)

Metaspace used 9214K, capacity 10134K, committed 10240K, reserved 1058816K

class space used 790K, capacity 841K, committed 896K, reserved 1048576K

通过mat分析oom时候自动dump的文件

首先发现应用程序类加载器 AppClassLoader 加载了很多东西

cglib 总共动态生成了 668个类

list outgoing objects 进去看,这个名字怪怪的类 父类是 Car, 关联了一堆 cglib的代理对象 也就是说肯定是通过cglib加强 car 的时候有问题

Bean找对象方法执行

package cn.wisefly.miims.util;

import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

import org.springframework.stereotype.Component;

import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;

@Component

public class SpringReflectUtils implements ApplicationContextAware {

    /**

    * Spring容器 spring应用上下文对象

    */

    private static ApplicationContext applicationContext;

    @Override

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

        SpringReflectUtils.applicationContext = applicationContext;

        System.out.println(“========ApplicationContext配置成功,在普通类可以通过调用SpringUtil.getAppContext()获取applicationContext对象,applicationContext=” + SpringReflectUtils.applicationContext + “========”);

    }

    /**

    * 对象名称获取spring bean对象

    * @param name

    * @return

    * @throws BeansException

    */

    public static Object getBean(String name) throws BeansException {

        return applicationContext.getBean(name);

    }

    /**

    * 根据 服务名称 ,方法名 反射调用  spring bean 中的 方法

    * @param serviceName 服务名

    * @param methodName 方法名

    * @param params 参数

    * @return

    * @throws Exception

    */

    public static Object springInvokeMethod(String serviceName, String methodName, Object[] params) throws Exception {

        Object service = getBean(serviceName);

        Class? extends Object[] paramClass = null;

        if (params != null) {

            int paramsLength = params.length;

            paramClass = new Class[paramsLength];

            for (int i = 0; i paramsLength; i++) {

                paramClass[i] = params[i].getClass();

            }

        }

        // 找到方法

        Method method = ReflectionUtils.findMethod(service.getClass(), methodName, paramClass);

        // 执行方法

        return ReflectionUtils.invokeMethod(method, service, params);

    }

}

后端自定义的异常 在dubbo 怎么抛到前端

public Result invoke(Invoker? invoker, Invocation invocation) throws RpcException {

try {

Result result = invoker.invoke(invocation);

if (result.hasException() GenericService.class != invoker.getInterface()) {

try {

Throwable exception = result.getException();

// 如果是checked异常,直接抛出

if (! (exception instanceof RuntimeException) (exception instanceof Exception)) {

return result;

}

// 在方法签名上有声明,直接抛出

try {

Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());

Class?[] exceptionClassses = method.getExceptionTypes();

for (Class? exceptionClass : exceptionClassses) {

if (exception.getClass().equals(exceptionClass)) {

return result;

}

}

} catch (NoSuchMethodException e) {

return result;

}

// 未在方法签名上定义的异常,在服务器端打印ERROR日志

logger.error(“Got unchecked and undeclared exception which called by ” + RpcContext.getContext().getRemoteHost()

+ “. service: ” + invoker.getInterface().getName() + “, method: ” + invocation.getMethodName()

+ “, exception: ” + exception.getClass().getName() + “: ” + exception.getMessage(), exception);

// 异常类和接口类在同一jar包里,直接抛出

String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());

String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());

if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)){

return result;

}

// 是JDK自带的异常,直接抛出

String className = exception.getClass().getName();

if (className.startsWith(“java.”) || className.startsWith(“javax.”)) {

return result;

}

// 是Dubbo本身的异常,直接抛出

if (exception instanceof RpcException) {

return result;

}

// 否则,包装成RuntimeException抛给客户端

return new RpcResult(new RuntimeException(StringUtils.toString(exception)));

} catch (Throwable e) {

logger.warn(“Fail to ExceptionFilter when called by ” + RpcContext.getContext().getRemoteHost()

+ “. service: ” + invoker.getInterface().getName() + “, method: ” + invocation.getMethodName()

+ “, exception: ” + e.getClass().getName() + “: ” + e.getMessage(), e);

return result;

}

}

return result;

} catch (RuntimeException e) {

logger.error(“Got unchecked and undeclared exception which called by ” + RpcContext.getContext().getRemoteHost()

+ “. service: ” + invoker.getInterface().getName() + “, method: ” + invocation.getMethodName()

+ “, exception: ” + e.getClass().getName() + “: ” + e.getMessage(), e);

throw e;

}

}

所以在dubbo的service端想抛出自定义异常,只能通过在service端的接口方法上声明所要抛出的异常,或者将异常类与接口同包,再或者是接口的实现类再实现dubbo的GenericService接口。

对于第一种方案没有使用,因为它对代码的入侵比较严重。

第二种方案可以实现,可对于目前的业务框架,让接口类和异常类同包则变得不太可能。

所以最后选择了让接口实现类再实现GenericService接口,而对于其需要实现的$invoke方法则没有做任何的方法体处理,直接废弃。

对于dubbo的service端自定义异常类的处理,有些不理解的就是,为什么dubbo需要对自定义异常类做一次Runtime异常的转化,而不是直接抛出原异常类型。或者有没有对dubbo更了解的朋友,有对自定义异常更好的处理方法。

包含javareflectutils的词条

javareflectutils的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于、javareflectutils的信息别忘了在本站进行查找喔。

本文来自投稿,不代表【】观点,发布者:【

本文地址: ,如若转载,请注明出处!

举报投诉邮箱:253000106@qq.com

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2024年4月2日 20:38:19
下一篇 2024年4月2日 20:46:32

相关推荐

  • 包含linuxiisaccess的词条

    毕业论文:linux系统的web服务器架设 1、我们以RedHat Linux 0系统为例,想要linuxconf在Web浏览器环境工作,必须进行以下设置: * 在gnome-linuxconf对话框中,打开“Config/Networking/Misc/Linuxconf network access”分支,选中“Enable netwoork acces…

    2024年5月23日
    4400
  • 包含黑客技术学习网址的词条

    信息安全技术专业的相关学习网站有哪些? 1、关于学习类的网站有掌门1对多贝、网易云课堂、慕课、传课、CSDN、我要自学网等等。 2、网络安全主要集中在大型城市,如北京上海广州深圳等,那里安全公司特别多,如360,天融信,奇安信等,所以学习网络安全建议选择这些城市。 3、入侵检测系统技术(IDS);加密&VPN技术;产品安全;安全管理。基础课程的主要内…

    2024年5月23日
    5000
  • 包含c语言对txt文件命名的词条

    如何在C语言编程里面修改源文件名字 如果你是在WINDOWS的话,简单了,随便用个编辑器,比如记事本,然后写c源程序,保存到你想要保存的位置。如果你在DOS下,可以用edit,写好以后,按alt键,选择文件菜单,然后保存。 用open打开文件,注意操作模式使用“修改”或者“添加” 用write或者fprintf向文件中写入你的内容。 用close关闭文件。 …

    2024年5月23日
    4800
  • 包含linux启动xinetd的词条

    简述linux进程的启动.终止的方式以及如何查看进程 查看启动的进程:可以使用以面命令来查看:01ps -ef |grep tomcat复制代码tomcat它是一个Java进程,所以查找Java进程也可查找出来。 ps -ef|grep java复制代码可以看到用户和进程编号,可以用kill 进程编号结束进程。 (1)手工启动 用户在输入端发出命令,直接启动…

    2024年5月23日
    4900
  • 包含linux内核二进制在内存分布的词条

    内存管理:一文读懂Linux内存组织结构及页面布局 (1)Linux虚拟内存实现机制 Linux虚拟内存的实现需要六种机制的支持:地址映射机制、内存分配回收机制、缓存和刷新机制、请求页机制、交换机制、内存共享机制。 Linux 内存管理是操作系统内核对物理内存的分配和管理。Linux 内存管理有两个基本任务:一是把可用的内存给程序使用,二是在物理内存不足时,…

    2024年5月23日
    4400
  • 包含Simcityjava的词条

    问一下各种程序的后缀 ,应用程序通常被分为两部分:图形用户接口(GUI)和引擎(Engien)。2,应用程序后缀名:(1)在DOS或Windows系统下其扩展名为*.exe或*.com;(2)在macosx下扩展名一般为*.app。 在windows操作系统下,可执行程序扩展名通常为.exe。全名executablefile,译作可执行文件,可移植可执行(P…

    2024年5月23日
    4600
  • 包含linuxnode后台运行的词条

    怎样使linux后台运行node服务指令 1、nohup node your_app.js & forever可以让我们做得更好,并且可以跨平台的在windows和Linux下都能运行。 2、安装指定版本的node.js(服务器基本软件的安装)你可以到nodejs org官网上面找到相对的tar.gz文件包,下载然后进行源码安装。 3、nodejs一…

    2024年5月23日
    3900
  • 包含hypervlinux集成服务的词条

    如何在Linux发行版中安装并启用Hyper-V集成服务 1、方法/步骤 在网上下载好linux系统的集成服务,并插入hyper-v磁盘中。用root 用户登录linux系统。linux系统自动载入cd rom 中。选择 install.sh,选择运行。运行中,重启电脑。 2、在Hyper-V控制台新建虚机,注意虚机的网卡先选择“旧版网络适配器”,主要是方便…

    2024年5月23日
    3900
  • 包含javajbtok的词条

    java的语法 1、Java的基本语法如下:大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的。类名:对于所有的类来说,类名的首字母应该大写。 2、Java中区分大小写。类和接口名首字母必须大写,采用驼峰命名法,每一个名单词的首字母大写,例如:MyFirstJavaProgram;类名和源文件名必须一致。 3、关键字是电脑语言…

    2024年5月23日
    4000
  • 包含excelvbasaveas的词条

    如何用VBA新建一个新的excel表并将其保存在指定目录下 如下图所示,我想将桌面上第一章中的每个工作簿名称放置到工作表中。新建一个工作簿,将其命名为“第一章目录”,按alt+f11组合键,打开宏界面。 新建一个模块,将代码复制到到这个模块中,就会将当前工作表保存到thisworkbook目录下,并以txt格式来保存。 excel中使用vba来创建新的工作薄…

    2024年5月23日
    4900

发表回复

登录后才能评论



关注微信