摘要:方案一設(shè)置運(yùn)行環(huán)境變量運(yùn)行后會(huì)把文件生成在目錄下動(dòng)態(tài)代理時(shí)生成文件缺點(diǎn)是只適用于動(dòng)態(tài)代理方案二使用可以出中所有已加載的。
由于動(dòng)態(tài)代理生成的class是直接以二進(jìn)制的方式加載進(jìn)內(nèi)存中的,并沒有對(duì)應(yīng)的.class文件生成,所以如果想通過反編譯工具查看動(dòng)態(tài)代理生成的代碼需要通過特殊的手段來處理。
方案一設(shè)置運(yùn)行環(huán)境變量,運(yùn)行后會(huì)把class文件生成在classpath目錄下
//動(dòng)態(tài)代理時(shí)生成class文件 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
缺點(diǎn)是只適用于JDK動(dòng)態(tài)代理
方案二使用ClassDump,可以dump出JVM中所有已加載的class。ClassDump位于$JAVA_HOME/lib/sa-jdi.jar中(注:windows版本JDK從1.7開始才有此工具),直接以命令行執(zhí)行。
#查看PID E:workTestin>jps #缺省輸出該P(yáng)ID下所有已加載的class文件至./目錄 E:workTestin>java -classpath ".;./bin;%JAVA_HOME%/lib/sa-jdi.jar" sun.jvm.hotspot.tools.jcore.ClassDump
//導(dǎo)入sa-jdi.jar包,實(shí)現(xiàn)ClassFilter接口,只輸出匹配的class文件 public class MyFilter implements ClassFilter{ @Override public boolean canInclude(InstanceKlass arg0) { return arg0.getName().asString().startsWith("com/sun/proxy/$Proxy0"); } }
#查看PID E:workTestin>jps #使用ClassFilter輸出匹配的class文件,并指定輸出目錄 E:workTestin>java -classpath ".;./bin;%JAVA_HOME%/lib/sa-jdi.jar" -Dsun.jvm.hotspot.tools.jcore.filter=proxy.MyFilter -Dsun.jvm.hotspot.tools.jcore.outputDir=e:/dump sun.jvm.hotspot.tools.jcore.ClassDump
此方案基于JVM層的ClassDump所以可以支持javassist、cglib、asm動(dòng)態(tài)生成的class。
最后貼下JDK動(dòng)態(tài)代理反編譯出來的代碼package com.sun.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; import proxy.Run; //目標(biāo)代理類接口 //繼承了Proxy類,實(shí)現(xiàn)目標(biāo)代理類接口 public final class $Proxy0 extends Proxy implements Run { private static Method m1; private static Method m3; private static Method m0; private static Method m2; public $Proxy0(InvocationHandler paramInvocationHandler) { super(paramInvocationHandler); } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); //獲取目標(biāo)代理類的方法 m3 = Class.forName("proxy.Run").getMethod("run", new Class[0]); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); return; } catch (NoSuchMethodException localNoSuchMethodException) { throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); } catch (ClassNotFoundException localClassNotFoundException) { throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); } } //方法重寫 public final String run() { try { //this.h就是InvocationHandler的實(shí)現(xiàn)類了,調(diào)用invoke方法,在實(shí)現(xiàn)類里面做攔截處理 return (String)this.h.invoke(this, m3, null); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final boolean equals(Object paramObject) { try { return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue(); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String toString() { try { return (String)this.h.invoke(this, m2, null); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int hashCode() { try { return ((Integer)this.h.invoke(this, m0, null)).intValue(); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } }參考
http://rednaxelafx.iteye.com/blog/727938
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/67807.html
摘要:第一個(gè)大陡坡是應(yīng)用發(fā)布,老年代內(nèi)存占比下降,很正常。但此時(shí)老年代內(nèi)存使用占比。因?yàn)楹笃诓⒉粫?huì)引發(fā)??梢钥闯?,由于到達(dá)時(shí)候,觸發(fā)了一次和一次。但觸發(fā)時(shí),占比并沒用明顯的規(guī)律。得出,擴(kuò)容導(dǎo)致這個(gè)說法,其實(shí)是不準(zhǔn)確的。 轉(zhuǎn)載請(qǐng)注明原文鏈接:https://www.jianshu.com/p/468... 某天早上,毛老師在群里問「cat 上怎么看 gc」。 showImg(https://...
摘要:打印等待回收對(duì)象的信息可以看到當(dāng)前隊(duì)列中并沒有等待線程執(zhí)行方法的對(duì)象。一般情況,會(huì)到客戶端用工具來分析用于生成虛擬機(jī)當(dāng)前時(shí)刻的線程快照。 運(yùn)用jvm自帶的命令可以方便的在生產(chǎn)監(jiān)控和打印堆棧的日志信息幫忙我們來定位問題!雖然jvm調(diào)優(yōu)成熟的工具已經(jīng)有很多:jconsole、大名鼎鼎的VisualVM,IBM的Memory Analyzer等等,但是在生產(chǎn)環(huán)境出現(xiàn)問題的時(shí)候,一方面工具的使...
摘要:結(jié)構(gòu)型模式適配器模式橋接模式裝飾模式組合模式外觀模式享元模式代理模式。行為型模式模版方法模式命令模式迭代器模式觀察者模式中介者模式備忘錄模式解釋器模式模式狀態(tài)模式策略模式職責(zé)鏈模式責(zé)任鏈模式訪問者模式。 主要版本 更新時(shí)間 備注 v1.0 2015-08-01 首次發(fā)布 v1.1 2018-03-12 增加新技術(shù)知識(shí)、完善知識(shí)體系 v2.0 2019-02-19 結(jié)構(gòu)...
摘要:虛擬機(jī)性能監(jiān)控與故障處理工具詳解概述本文參考的是周志明的深入理解虛擬機(jī)第四章,為了整理思路,簡(jiǎn)單記錄一下,方便后期查閱。虛擬機(jī)堆轉(zhuǎn)儲(chǔ)快照分析工具功能用于分析生成的。 虛擬機(jī)性能監(jiān)控與故障處理工具 詳解 4.1 概述 本文參考的是周志明的 《深入理解Java虛擬機(jī)》 第四章 ,為了整理思路,簡(jiǎn)單記錄一下,方便后期查閱。 JDK本身提供了很多方便的JVM性能調(diào)優(yōu)監(jiān)控工具,除了集成式的Vis...
摘要:用戶態(tài)不能干擾內(nèi)核態(tài)所以指令就有兩種特權(quán)指令和非特權(quán)指令不同的狀態(tài)對(duì)應(yīng)不同的指令。非特權(quán)指令所有程序均可直接使用。用戶態(tài)常態(tài)目態(tài)執(zhí)行非特權(quán)指令。 這是我今年從三月份開始,主要的大廠面試經(jīng)過,有些企業(yè)面試的還沒來得及整理,可能有些沒有帶答案就發(fā)出來了,還請(qǐng)各位先思考如果是你怎么回答面試官?這篇文章會(huì)持續(xù)更新,請(qǐng)各位持續(xù)關(guān)注,希望對(duì)你有所幫助! 面試清單 平安產(chǎn)險(xiǎn) 飛豬 上汽大通 浩鯨科...
閱讀 2701·2021-11-08 13:16
閱讀 2378·2021-10-18 13:30
閱讀 2250·2021-09-27 13:35
閱讀 2004·2019-08-30 15:55
閱讀 2455·2019-08-30 13:22
閱讀 593·2019-08-30 11:24
閱讀 2087·2019-08-29 12:33
閱讀 1822·2019-08-26 12:10