日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

java逻辑第九章_深入理解jvm-(第九章)类加载及执行子系统的案例与实战

發(fā)布時(shí)間:2025/4/5 windows 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java逻辑第九章_深入理解jvm-(第九章)类加载及执行子系统的案例与实战 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載自:http://blog.csdn.net/coslay/article/details/49564789

概述

在Class文件格式與執(zhí)行引擎這部分中,用戶的程序能直接影響的內(nèi)容并不太多,

Class文件以何種格式存儲(chǔ),類型何時(shí)加載、如何連接,以及虛擬機(jī)如何執(zhí)行字節(jié)碼指令等都是由虛擬機(jī)直接控制的行為,用戶程序無(wú)法對(duì)其進(jìn)行改變。能通過(guò)程序進(jìn)行操作的,主要是字節(jié)碼生成與類加載器這兩部分的功能,但僅僅在如何處理這兩點(diǎn)上,就已經(jīng)出現(xiàn)了許多值得欣賞和借鑒的思路,這些思路后來(lái)成為了許多常用功能和程序?qū)崿F(xiàn)的基礎(chǔ)。

案例分析

Tomcat:正統(tǒng)的類加載器架構(gòu)

主流的Java Web服務(wù)器

,如Tomcat、Jetty、WebLogic、WebSphere或其他筆者沒(méi)有列舉的服務(wù)器,都實(shí)現(xiàn)了自己定義的類加載器(一般都不止一個(gè))。因?yàn)橐粋€(gè)功能健全的Web服務(wù)器

,要解決如下幾個(gè)問(wèn)題:

部署在同一個(gè)服務(wù)器上的兩個(gè)Web應(yīng)用程序所使用的Java類庫(kù)可以實(shí)現(xiàn)相互隔離。這是最基本的需求,兩個(gè)不同的應(yīng)用程序可能會(huì)依賴同一個(gè)第三方類庫(kù)的不同版本,不能要求一個(gè)類庫(kù)在一個(gè)服務(wù)器中只有一份,服務(wù)器應(yīng)當(dāng)保證兩個(gè)應(yīng)用程序的類庫(kù)可以互相獨(dú)立使用。

部署在同一個(gè)服務(wù)器上的兩個(gè)Web應(yīng)用程序所使用的Java類庫(kù)可以互相共享。這個(gè)需求也很常見(jiàn),例如,用戶可能有10個(gè)使用Spring組織的應(yīng)用程序部署在同一臺(tái)服務(wù)器上,如果把10份Spring分別存放在各個(gè)應(yīng)用程序的隔離目錄中,將會(huì)是很大的資源浪費(fèi)——這主要倒不是浪費(fèi)磁盤空間的問(wèn)題,而是指類庫(kù)在使用時(shí)都要被加載到服務(wù)器內(nèi)存,如果類庫(kù)不能共享

,虛擬機(jī)的方法區(qū)就會(huì)很容易出現(xiàn)過(guò)度膨脹的風(fēng)險(xiǎn)。

服務(wù)器需要盡可能地保證自身的安全不受部署的Web應(yīng)用程序影響。目前,有許多主流的Java

Web服務(wù)器自身也是使用Java語(yǔ)言來(lái)實(shí)現(xiàn)的。因此

,服務(wù)器本身也有類庫(kù)依賴的問(wèn)題,一般來(lái)說(shuō),基于安全考慮,服務(wù)器所使用的類庫(kù)應(yīng)該與應(yīng)用程序的類庫(kù)互相獨(dú)立。

支持JSP應(yīng)用的Web服務(wù)器 ,大多數(shù)都需要支持HotSwap功能。我們知道,JSP文件最終要編譯成Java

Class才能由虛擬機(jī)執(zhí)行,但JSP文件由于其純文本存儲(chǔ)的特性,運(yùn)行時(shí)修改的概率遠(yuǎn)遠(yuǎn)大于第三方類庫(kù)或程序自身的Class文件。而且ASP、PHP和JSP這些網(wǎng)頁(yè)應(yīng)用也把修改后無(wú)須重啟作為一個(gè)很大的“優(yōu)勢(shì)”來(lái)看待,因此“主流”的Web服務(wù)器都會(huì)支持JSP生成類的熱替換,當(dāng)然也有“非主流”的

,如運(yùn)行在生產(chǎn)模式( Production Mode ) 下的WebLogic服務(wù)器默認(rèn)就不會(huì)處理JSP文件的變化。

由于存在上述問(wèn)題,在部署Web應(yīng)用時(shí)

,單獨(dú)的一個(gè)ClassPath就無(wú)法滿足需求了,所以各種Web服務(wù)器都“不約而同”地提供了好幾個(gè)ClassPath路徑供用戶存放第三方類庫(kù),這些路徑一般都以“l(fā)ib”或“classes”命名。被放置到不同路徑中的類庫(kù),具備不同的訪問(wèn)范圍和服務(wù)對(duì)象,通常,每一個(gè)目錄都會(huì)有一個(gè)相應(yīng)的自定義類加載器去加載放置在里面的Java類庫(kù)。

現(xiàn)在 ,筆者就以Tomcat服務(wù)器為例,看一看Tomcat具體是如何規(guī)劃用戶類庫(kù)結(jié)構(gòu)和類加載器的。

在Tomcat目錄結(jié)構(gòu)中,有3組目錄(“/common public class HotSwapClassLoader extends ClassLoader { public HotSwapClassLoader()

{ super(HotSwapClassLoader.class.getClassLoader()); }

public Class loadByte(byte[]

classByte) { return defineClass(null,

classByte, 0, classByte.length); } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

HotSwapClassLoader所做的事情僅僅是公開(kāi)父類(即

中的protected方法defineClass()

,我們將會(huì)使用這個(gè)方法把提交執(zhí)行的

或findClass() 方法 ,因此如果不算外部手工調(diào)用loadByte()

方法的話,這個(gè)類加載器的類查找范圍與它的父類加載器是完全一致的,在被虛擬機(jī)調(diào)用時(shí),它會(huì)按照雙親委派模型交給父類加載。構(gòu)造函數(shù)中指定為加載HotSwapClassLoader類的類加載器也為父類加載器,這一步是實(shí)現(xiàn)提交的執(zhí)行代碼可以訪問(wèn)服務(wù)端引用類庫(kù)的關(guān)鍵,下面我們來(lái)看看代碼清單9-3。

第二個(gè)類是實(shí)現(xiàn)將java.lang.System替換為我們自己定義的HackSystem類的過(guò)程,它直接修改符合Class文件格式的byte[]數(shù)組中的常量池部分,將常量池中指定內(nèi)容的

CONSTANT_UtfB_info常量替換為新的字符串,具體代碼如代碼清單9-4所示。

ClassModifier中涉及對(duì)byte[]數(shù)組操作的部分,主要是將byte[]與int和String互相轉(zhuǎn)換,以及把對(duì)byte[]數(shù)據(jù)的替換操作封裝在代碼清單9-5所示的ByteUtils中。

代碼清單9-4

ClassModifier的實(shí)現(xiàn)

public class ClassModifier {

private static final int CONSTANT_POOL_COUNT_INDEX = 8;

private static final int CONSTANT_Utf8_info = 1;

private static final int[] CONSTANT_ITEM_LENGTH = { -1, -1, -1, 5, 5, 9, 9, 3, 3, 5, 5, 5, 5 };

private static final int u1 = 1;

private static final int u2 = 2;

private byte[] classByte;

public ClassModifier(byte[] classByte) {

this.classByte = classByte;

}

public byte[] modifyUTF8Constant(String oldStr, String newStr) {

int cpc = getConstantPoolCount();

int offset = CONSTANT_POOL_COUNT_INDEX + u2;

for (int i = 0; i < cpc; i++) {

int tag = ByteUtils.bytes2Int(classByte, offset, u1);

if (tag == CONSTANT_Utf8_info) {

int len = ByteUtils.bytes2Int(classByte, offset + u1, u2);

offset += (u1 + u2);

String str = ByteUtils.bytes2String(classByte, offset, len);

if (str.equalsIgnoreCase(oldStr)) {

byte[] strBytes = ByteUtils.string2Bytes(newStr);

byte[] strLen = ByteUtils.int2Bytes(newStr.length(), u2);

classByte = ByteUtils.bytesReplace(classByte, offset - u2, u2, strLen);

classByte = ByteUtils.bytesReplace(classByte, offset, len, strBytes);

return classByte;

} else {

offset += len;

}

} else {

offset += CONSTANT_ITEM_LENGTH[tag];

}

}

return classByte;

}

public int getConstantPoolCount() {

return ByteUtils.bytes2Int(classByte, CONSTANT_POOL_COUNT_INDEX, u2);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

代碼清單9-5

ByteUtils的實(shí)現(xiàn)

public class ByteUtils {

public static int bytes2Int(byte[] b, int start, int len) {

int sum = 0;

int end = start + len;

for (int i = start; i < end; i++) {

int n = ((int) b[i]) & 0xff;

n <<= (--len) * 8;

sum = n + sum;

}

return sum;

}

public static byte[] int2Bytes(int value, int len) {

byte[] b = new byte[len];

for (int i = 0; i < len; i++) {

b[len - i - 1] = (byte) ((value >> 8 * i) & 0xff);

}

return b;

}

public static String bytes2String(byte[] b, int start, int len) {

return new String(b, start, len);

}

public static byte[] string2Bytes(String str) {

return str.getBytes();

}

public static byte[] bytesReplace(byte[] originalBytes, int offset, int len, byte[] replaceBytes) {

byte[] newBytes = new byte[originalBytes.length + (replaceBytes.length - len)];

System.arraycopy(originalBytes, 0, newBytes, 0, offset);

System.arraycopy(replaceBytes, 0, newBytes, offset, replaceBytes.length);

System.arraycopy(originalBytes, offset + len, newBytes, offset + replaceBytes.length, originalBytes.length - offset - len);

return newBytes;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

經(jīng)過(guò)ClassModifier處理后的byte[]數(shù)組才會(huì)傳給HotSwapClassLoader.loadByte()方法進(jìn)行類加載,byte[]數(shù)組在這里替換符號(hào)引用之后,與客戶端直接在

,又避免了服務(wù)端修改標(biāo)準(zhǔn)輸出后影響到其他程序的 輸出。下面我們來(lái)看看代碼清單9-4和代碼清單9-5。

public class HackSystem {

public final static InputStream in = System.in;

private static ByteArrayOutputStream buffer = new ByteArrayOutputStream();

public final static PrintStream out = new PrintStream(buffer);

public final static PrintStream err = out;

public static String getBufferString() {

return buffer.toString();

}

public static void clearBuffer() {

buffer.reset();

}

public static void setSecurityManager(final SecurityManager s) {

System.setSecurityManager(s);

}

public static SecurityManager getSecurityManager() {

return System.getSecurityManager();

}

public static long currentTimeMillis() {

return System.currentTimeMillis();

}

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {

System.arraycopy(src, srcPos, dest, destPos, length);

}

public static int identityHashCode(Object x) {

return System.identityHashCode(x);

}

// 下面所有的方法都與java.lang.System的名稱一樣

// 實(shí)現(xiàn)都是字節(jié)轉(zhuǎn)調(diào)System的對(duì)應(yīng)方法

// 因版面原因,省略了其他方法

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

至此,

4個(gè)支持類已經(jīng)講解完畢,我們來(lái)看看最后一個(gè)類JavaClassExecuter ,

它是提供給外部調(diào)用的入口,調(diào)用前面幾個(gè)支持類組裝邏輯,完成類加載工作。方法,如果期間出現(xiàn)任何異常,將異常信息打印到HackSystemout中,最后把緩沖區(qū)中的信息、作為方法的結(jié)果返回。JavaClassExecuter的實(shí)現(xiàn)代碼如代運(yùn)清單9-

7所示。

代碼清單9-7

JavaClassExecuter的實(shí)現(xiàn)

public class JavaClassExecuter {

public static String execute(byte[] classByte) {

HackSystem.clearBuffer();

ClassModifier cm = new ClassModifier(classByte);

byte[] modiBytes = cm.modifyUTF8Constant("java/lang/System", "org/fenixsoft/classloading/execute/HackSystem");

HotSwapClassLoader loader = new HotSwapClassLoader();

Class clazz = loader.loadByte(modiBytes);

try {

Method method = clazz.getMethod("main", new Class[] { String[].class });

method.invoke(null, new String[] { null });

} catch (Throwable e) {

e.printStackTrace(HackSystem.out);

}

return HackSystem.getBufferString();

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

驗(yàn)證

遠(yuǎn)程執(zhí)行功能的編碼到此就完成了,接下來(lái)就要檢驗(yàn)一下我們的勞動(dòng)成果了。如果只是測(cè)試的話,那么可以任意寫(xiě)一個(gè)Java類

,內(nèi)容無(wú)所謂,只要向System.out輸出信息即可,取名為TestClass,

同時(shí)放到服務(wù)器C盤的根目錄中。然后,建立一個(gè)JSP文件并加入如代碼清單9-

8所示的內(nèi)容,就可以在瀏覽器中看到這個(gè)類的運(yùn)行結(jié)果了。

總結(jié)

以上是生活随笔為你收集整理的java逻辑第九章_深入理解jvm-(第九章)类加载及执行子系统的案例与实战的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成年人黄国产 | 久久3p | 伊人青青草 | 欧美一区二区福利视频 | 国产片网站 | 国产精品乱码一区二三区小蝌蚪 | 日韩一区二区三区四区五区六区 | 日韩一级片av | 视频在线不卡 | 青青插 | 美女脱得一干二净 | av天堂永久资源网 | 法国伦理少妇愉情 | 国产露脸无套对白在线播放 | 窝窝视频在线 | 日韩污视频在线观看 | 四虎av影院 | 三级电影网址 | 欧美视频导航 | 夜久久| 天堂а√在线中文在线新版 | 无码无遮挡又大又爽又黄的视频 | 成人污污www网站免费丝瓜 | 肉视频在线观看 | 肉嫁高柳家在线看 | 亚色中文 | 97视频播放| xxxx 国产 | 九色蝌蚪视频 | av在线首页| 日韩在线精品视频 | 色诱视频在线观看 | 日韩精品久久一区二区 | 久久综合久久久久 | 国产日产欧洲无码视频 | 91娇羞白丝网站 | 成人3d动漫一区二区三区91 | 成人污污www网站免费丝瓜 | 欧美精品成人久久 | 欧美中文字幕在线 | 精品一区中文字幕 | 国产精品久久久久久久久久东京 | 污网站免费 | 亚洲成人福利 | 日韩毛片免费观看 | 国产精品一区二区精品 | 欧美肥老妇视频九色 | 欧美视频日韩 | 美女扒开尿口让男人捅爽 | 国产精品久久免费视频 | 欧美日韩激情一区 | 日本不卡在线 | 成人亚洲玉足脚交系列 | 日韩黄色免费视频 | 国产精品无码一区二区桃花视频 | 国产精品久久久久久久久免费相片 | 国产一区视频在线观看免费 | 日韩伦理中文字幕 | 亚洲+小说+欧美+激情+另类 | 久精品国产 | 波多野结衣高清电影 | 欧美日韩电影一区 | 亚洲国产精品久久久久 | 亚洲日本在线观看视频 | 黑人操中国女人视频 | 欧美日韩国产精品综合 | 78m78成人免费网站 | 男生操女生在线观看 | 日韩精品免费一区二区夜夜嗨 | 五月天堂婷婷 | 日本美女日批视频 | 亚洲二区在线视频 | 日本美女在线 | 日韩激情图片 | 香蕉伊人 | 五月婷婷伊人网 | 性欧美高清 | 欧美顶级毛片在线播放 | av片久久| 免费看片视频 | 成人手机在线观看 | 国产精品久久久久91 | 美女狂揉羞羞的视频 | 成人午夜免费在线观看 | 成人免费毛片高清视频 | 色综合av综合无码综合网站 | 久久视频在线观看 | 91精品国产综合久久福利软件 | 国产suv精品一区二区69 | 亚洲超丰满肉感bbw 悠悠av | 国产精品xxx在线观看 | 久久久国产精品黄毛片 | 日韩视频一区 | 日b视频在线观看 | 亚洲成人视屏 | 青草精品| 精品人妻一区二区三区浪潮在线 | 国产美女被草 | 四虎综合网 |