自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

高手支招 Java經(jīng)驗分享(十二)

開發(fā) 后端
本篇文章是作者Ant_Yan在CSDN論壇上發(fā)布的自己對Java學習的一些經(jīng)驗分享。這是他經(jīng)驗分享的第十二部分,主要介紹作者學習JVM的心得。

  作為一個Java程序員,如果不了解JVM的工作原理,就很難從底層去把握Java語言和Java程序的運作機制。這里先推薦一個最權威的講解JVM的文檔,大家只要查過Java API的可以在里面的一個叫“API, Language, and Virtual Machine Document”的標題下看到四個子標題,***個是我們最熟悉的Java API Specification,很少會有人注意到第三和第四個子標題,分別是“The Java Language Specification”和“The Java Machine Specification”后面都帶有(Download)字樣,JVM的那個URL直接鏈接到http://java.sun.com/docs/books/vmspec/2nd-edition/這里地址。我們可以下載到一份非常權威詳細的講解JVM原理的官方文檔。筆者業(yè)余時間花了1個星期來閱讀,這里把自己的收獲跟大家來分享一下,大概從這么幾個方面來談一談:

  1. JVM的實現(xiàn)機制

  Java虛擬機就是一個小的計算機,有自己的指令集,有自己的文件系統(tǒng),管理內部的表和數(shù)據(jù),負責讀取class文件里面字節(jié)碼,然后轉換成不同操作系統(tǒng)的CPU指令,從而使得Java程序在不同的操作系統(tǒng)上順利的跑起來。所以Window的JVM能把字節(jié)碼轉換成Window系統(tǒng)的指令集,Linux的JVM能把字節(jié)碼轉換成Linux系統(tǒng)的字節(jié),同理還有Solaris,它們彼此之間是不能通用的。最早一款的原型雖然是Sun公司開發(fā)的,但發(fā)展到現(xiàn)在其實任何廠商都可以自己去實現(xiàn)一個虛擬機,用來讀取字節(jié)碼轉換成OS指令。甚至我們可以認為JVM跟Java編程語言都沒有關系,因為你自己哪怕用記事本寫一串字節(jié)碼,也可以讓JVM來解析運行,只要你的字節(jié)碼能通過JVM的驗證。

  JVM的驗證其實是很嚴格的,這里只講一些有趣的地方。大家還記得Java的圖標是一個杯咖啡麼?究其歷史我們也許可以查出為什么,但還有更顯而易見的方式是JVM怎么判斷一個文件是否是class文件?JVM的做法是讀取前4個字節(jié)轉換成16進制數(shù),判斷是否等于0xCAFEBABE這個數(shù)。注意到這個單詞了麼?“cafebabe”,代表著國外一種咖啡品牌,似乎叫做Peet’s coffee-baristas之類。創(chuàng)造Java的人為了方便記憶,選擇了這樣一個16進制數(shù)作為標準class文件的頭,所以任何class文件都必須具有這4個字節(jié)的頭部。我們可以用DataInput這個接口的實現(xiàn)類來驗證一下,讀取任何一個class文件的***個int,int在Java里面是四個字節(jié)。轉換成16進制一定會是0xcafebabe的。

  所以這里想告訴大家的是,JVM其實并沒有那么神秘,我們完全可以理解它的構造。

  2. Java相關的基礎概念

  配合JVM的結構,在Java語言中也會有很多特點比較鮮明的地方。比如對數(shù)值計算從來不會檢查位溢出。任何變量存儲的二進制即使位全部為1了仍然可以加,全部為0了仍然可以減。大家只要稍微測試一下就知道了,看這幾個例子:

  1. int max = Integer.MAX_VALUE;  
  2. int min = Integer.MIN_VALUE;  
  3. max+1 == min; //true  
  4. min-1 == max; //true  
  5. 0.0/0.0 //得到“NaN”(Not a number)  
  6. 1/0.0 //Infinity  
  7. -1/0.0 //-Infinity  
  8. 1或-1/0 //ArithmeticException唯一的異常情況 

  看完這幾個例子,大家是否能更好的把握Java的數(shù)值運算呢?Java完全遵照IEEE-754的標準來定義單雙精度浮點數(shù)以及其他的數(shù)值存儲方式。

  另外Java里面有一個概念叫做Daemon Thread(守護線程),知道它的存在主要是為了理解虛擬機的生命周期。當我們運行java命令,從main函數(shù)進入的那一刻起,虛擬機就開始啟動運行了。Main所在的主線程也會啟動起來,它屬于非守護線程。與之同時一些守護線程也會同時啟動,最典型的守護線程代表就是GC(垃圾收集器)線程。JVM虛擬機什么時候退出呢?是在所有的非守護線程結束的那一刻,JVM就exit。注意這個時候守護線程并未退出,很可能還要繼續(xù)完成它的本職工作之后才會結束,但虛擬機的生命周期已經(jīng)提前于它結束了。

3. JVM內部的基本概念

  虛擬機內部還有一些概念,全部列舉是不現(xiàn)實的,太繁瑣也沒有意義。除非您真的想自己去做一個JVM。筆者只列舉部分概念:

  首先我們來看一個叫做ReturnAddress的變量,它是JVM用來存儲方法出口或者說進行跳轉的依據(jù),把任何地址存入這個變量就一定會按照這個地址來跳轉。我們需要注意的就是finally有比方法return更高的賦值給ReturnAddress的優(yōu)先級。同時存在方法return和finally return的話,一定是按照finally里面的return為準。

  JVM有自己的Heap,能被所有線程共享,存儲著所有的對象,內存是動態(tài)被分配的。對于每個線程,擁有自己的Stack,棧里面存儲的單位叫做Frame(楨)。楨里面就記錄著零時變量、對象引用地址、方法返回值等數(shù)據(jù)。JVM還有一個叫做Method Area的地方,存儲著一段一段的可執(zhí)行代碼,每一段就是一個方法體,也能被所有線程共享。所以我們說一個線程其實從run方法跑起來,跟它的類中聲明的其他方法是兩個概念。因為其他的方法包括的所有的對象,這個時候都充當為資源被線程使用。

  JVM有自己管理內存的方案,因為它具有文件系統(tǒng)的功能,我們可以看成一個小型的數(shù)據(jù)庫,內部有許許多多不同的表。表的字段可能是另外一張表的地址,也可以直接就是一個存儲數(shù)據(jù)值的地址值。JVM所有對運行時候類的解析驗證計算等管理工作,實際上都是在管理這些表的變動,如果我們從數(shù)據(jù)庫的角度來看,JVM所做的就是根據(jù)你的代碼來操作那么多個表***返回給你結果的過程。里面的表結構包括class的表、field表、method表、attribute表等。

  4. JVM的指令集

  JVM有自己的指令集,筆者從前也看過一些計算機組成結構和匯編語言的數(shù),建議大家也稍微看看,了解設計一個高效可用的計算機指令集是多么復雜又多么重要的過程。對于JVM的指令集,職責是管理好Java程序編譯出來的字節(jié)碼,相對而言指令集的名稱就多少和Java語言相關了,比如指令集里就有sastore,、saload表示array里面short的存和取、類似還有d2i表示從double轉換成int、monitorenter表示進入synchronized塊加鎖、getstatic和putstatic表示對靜態(tài)標量的存取、 jsr和ret等跳轉指令……

  為了便于記憶,設計JVM指令集的人們約定f開頭的跟float有關,d跟double有關,i跟int有關,s跟short有關,a跟array有關。有興趣的可以細讀文檔里面的每一個指令的作用。因為只是作為初步了解,這里就不多說了。

5. 一些Java關鍵字的實現(xiàn)原理

  文檔還很詳細的列舉了很多加載、初始化、加鎖等操作的過程。筆者覺得比較有用的***是記住Java里面只有Array不是由ClassLoader加載的對象,其他的對象全部都必須由一個ClassLoader來加載。另外package的概念除了類似于C++的namespace,是一種命名空間之外,底層的實現(xiàn)是規(guī)定同一個package下的類必須由同一個類加載器來加載,所以package的概念還可以認為是被同一個類加載器加載的類。

  另外在多線程中,有很多細節(jié)值得去體會。每個線程有自己的Working memory,它們從能被共享的Main Memory中去讀數(shù)據(jù)、修改、然后再存回去。筆者一直認為線程就是數(shù)據(jù)庫里面事務的前身或者說祖先。我們只要稍微比較一下它們的行為,就會發(fā)現(xiàn)很多一致性。事務也是操作被事務共享的表數(shù)據(jù),你改完我改,順序不一致就會出現(xiàn)臟數(shù)據(jù),而線程同樣會出現(xiàn)臟數(shù)據(jù)。我們對線程加的鎖策略,同樣在事務中也有適用。當然多事務的情況顯然比多線程更加復雜,但我們只要理解了多線程,相信對學習數(shù)據(jù)庫事務的效果也是非常有幫助的。Java里面除了synchronized能夠幫助同步多線程之外,還有一個弱同步的操作關鍵字是volatile,它產(chǎn)生在變量上的約束在文檔中也有詳細的說明。因為很復雜,考慮到篇幅筆者就不打算解釋一遍了。

  好了,又是新的一篇結束了。不足之處大家盡管提出來,筆者愿意接受各種職責批評。這個帖子一直以來得到那么多朋友的大力支持和鼓勵,筆者在這里真誠的說一聲謝謝!

【編輯推薦】

  1. 新手入門:學習Java的一點經(jīng)驗心得
  2. 61條Java面向對象設計的經(jīng)驗原則
  3. 經(jīng)驗分享:我的JavaEE學習道路
  4. Java對象類型轉換的四個經(jīng)驗
  5. 高手支招 Java經(jīng)驗分享(一)
責任編輯:韓亞珊 來源: CSDN
相關推薦

2011-03-31 13:52:22

Java

2011-03-31 16:26:28

Java

2011-03-31 15:36:02

Java

2011-03-31 14:07:27

Java

2011-03-31 16:44:43

Java

2011-03-31 13:56:24

Java

2011-03-31 14:49:35

2011-03-31 13:32:13

Java

2011-04-07 13:18:00

管理軟件項目項目

2009-10-29 16:57:05

Oracle傳輸表空間

2018-06-19 08:12:55

2010-07-21 14:05:31

2014-05-28 10:55:11

Windows XP安全補丁

2010-08-18 14:19:01

無線路由器

2009-09-28 10:52:00

CCNA考試經(jīng)驗CCNA

2011-07-15 17:35:19

JavaScript

2009-12-07 11:11:46

PHP顯示圖片

2009-10-15 10:59:00

CCNA經(jīng)驗分享CCNA

2009-12-25 09:44:52

WPF窗口設置

2011-05-16 17:36:05

SEO
點贊
收藏

51CTO技術棧公眾號