Java用於嵌入式系統的十大優點和五個侷限

 Java語言的優點在於:它最初是由理解和信奉網絡計算夢想的一個小巧而專注的開發組設計的,雖然該語言最初的實施方案有點缺陷,但爲了這個夢想,他們很少在技術上妥協,結果誕生了一種專爲以相互通信爲主要目  
的的設備而設計的語言。有許多技術上的優點都可能會引導嵌入系統開發者選擇Java。

1.與處理器無關

Java的第一個優點就是與處理器無關,這個優點似乎與嵌入式系統沒什麼相干。傳統上,嵌入程序就是針對特定的微處理器設計並在其上運行的,而C語言程序的可移植性則可通過編譯或交叉編譯來保障。

但是在Sun公司的模型中,一個程序可能是存儲在一個系統上,而被下載並運行在另一個完全不同的系統上;設備可能從不同地方下載一些程序來在一個處理器上運行,或者不同的處理器運行一個程序,通過網絡在相互間傳遞數據。使用Java,一個嵌入式系統就可能成爲一個通用的通信設備,能下載並運行能完成特定任務的程序。

對嵌入式系統,這是一個新的模型,已經有一些開發者正在向它靠攏。例如,電視機頂盒的供應商已宣佈併入JVM,以使用戶能通過Java Applets在他們觀看電視的同時接收到的支持該電視節目的一些內容。這樣你在觀看足球比賽時,看到的支持內容就可以是對球員的技術統計,若你在看電影,看到的支持內容就可以是演員的背景資料。JVM還被移植到移動電話中,這樣用戶可接收股票報價信息、比賽分數及其他即時信息。

這是一個恰當的設計和實施模型,首先它可以使開發平臺的選擇更加靈活,無需在與目標相同的平臺上開發,也不用關心交叉編譯的問題,因爲Java字節碼能在任何有JVM的操作系統中運行。其次,這種模型帶來的另一個優點是幾乎所有的檢測和調試可以獨立於目標設備來進行。但是,一些數據輸入和硬件交互要求在目標(或是很好的仿真系統)上測試。由於個別JVM有時有兼容性的問題,你應該在所有將用到該程序的平臺上測試它。但一般來說,你並不要高級而昂貴的、配備有邏輯探針、ICE以及其它調試工具的、針對目標平臺的開發環境。

2.面向對象提高開發速度和可維護性

Java是一種純粹面向對象的語言。所有代碼和數據都是某個類的一部分,沒有全局變量或是獨立於類存在的代碼,一個對象是一個類的實例,對象是通過調用操作方法,或者說函數來操作的,而這些方法或函數也是類的一部分,對象的方法就對象的數據進行操作。Java類被組織成一個等級層次,在層次結構中,一個子類能夠繼承其超類的行爲,並可用子類所具備的一些特有功能來擴展其超類的功能。對象模型是你能定義對應真實事物的數據結構,使得程序的任務和任務如何實現者二者之間的轉換變得基本上透明。

Java類層次有六個主要的類(共有二十三個類)成爲類包(packages)。要應用任何包中的任何對象,你只需要申明那個包。你也擁有類層次中的全繼承性,任何層次深部的對象都可取用層次中較高處定義的所有方法。

面向對象的設計和編程的優點在於其開發速度和代碼的可維護性,許多面向對象的開發都能通過利用和更改現存類庫來完成,而不是創造一個新的結構。這就使開發加快了,Sun’s Java Workshop(一個完全用Java寫的IDE)的開發者能在幾個月內建立一個功能齊備的圖形IDE就是一個很好的證據。面向對象的方法還儘量使用自然的結構,使其有很高的可讀性,且可輕易更改和加強。

3.安全高

由於有了JVM,一個Java應用程序與操作系統或硬件完全隔絕,因此計算機病毒或其他作祟的代碼就很難獲得對設備的控制。虛擬機是主機設備和那些可能難以確定其質量和可靠性的軟件之間的一個保護層。

另外,Java設計者從該語言中去掉了指針變量的概念。Java不能任意訪問內存,只能讀寫有Java內存分配管理系統創建的對象。由於Java編譯器所強制的嚴格的分類機制,從理論上來說,訪問那些未分配給程序的內存區域是不可能的。這個限制使得要寫惡意代碼的程序變得非常困難了。當然,這個保護並不完善,有人已經在Java安全模型中找到漏洞,其中一些被Sun公司處理掉了。一些有天分但肆無忌憚的編程人員可能會寫些程序,有意但不直接地更改內存的內容,或從主機獲取密碼或其他信息。但是,JVM確實提供了一定的保護,使得幾乎不可能直接在硬件上運行代碼。

對Java applet施加的限制就更加嚴格了。由於Java applet被設計成從Internet上下載,因而被視爲不可信任的代碼,除非它包括你已認定爲可信任的主機的數字指紋。JVM在內存的一個稱之爲sandbox的區域運行諸如applet這種不可信任的代碼。它給每個applet分配資源和特權,並將其限定在這些分配區域範圍中。除了這些限制,sandbox模型還施加如下限制:禁止讀寫當地計算機文件系統;網絡操作被限止,禁止不被信任的代碼建立與任何計算機的網絡連接,從其下載的那臺計算機除外,它也不能在任何小於1024的端口號(爲標準網絡協議使用那些著名的端口所保留的端口範圍)上監聽和接受連接;在運行不被信任代碼的線程組以外,禁止訪問或創建線程。

4.內存管理簡單

Java的內存管理遠比其他語言簡單,因爲它不使用指針。當對象被實例化時,內存被動態分配。正如我們前面分析的,對個別內存地址的訪問被Java的設計者視爲一個對安全的潛在危險,因此,訪問也被禁止。而且,Sun的網絡模型已假定你也許不知道目標處理器,而引用專用內存地址變得沒有必要。去掉指針的結果不僅提高了安全性,還簡化了編程,錯誤也減少了。

爲了理解Java怎樣分配內存,我們來與C語言比較一下。在C語言中,可以用值或引用的方式來訪問數據。事實上,出於靈活性和控制考慮,非原始數據類型都由引用方式來存取,即通過指針訪問。因此,值和引用的不同變得非常清楚,特別是:因爲你不得不使用不同的符號(*和&)來存取數據。要用這兩種不同的訪問方式,你必須清楚理解它們是什麼以及你爲什麼應該使用這一個,而不使用那一個。

在Java中,由值和引用來存儲是無縫的,尤其因爲其符號都一樣。兩者間唯一不同在於數據類型本身:所有原始數據類型始終由值的方式存取;所有對象,包括字串、數組以及文件流,始終由引用方式訪問。聲明爲原始數據變量類型包含該變量的值,聲明爲對象的變量則包含對該對象(即該對象的地址)的一個引用,而非對象自身的引用。僅僅聲明一個對象變量並不給對象分配內存,你必須用“new”關鍵字來分配內存和創建對象。

這兩種方法最根本的不同在於:不可能象在C中那樣就Java內存地址做指針算術或其他操作。Java中對象的地址是相對的(或虛擬的),它由虛擬機任意分配,因此你沒有理由還想要指針地址。

5.具有垃圾收集功能

垃圾收集自動收集內存中未引用的內存,並將其歸回空閒內存鏈表中。JVM使用此功能將不在使用的內存還給系統。當Java程序說明並實例化一個對象或數組時,它僅僅做一個JVM請求,訪問其下面的系統內存(通常是通過主機操作系統)並分配內存,Java的垃圾收集系統通過內存收集對象,然後檢查它們的引用鏈。Java的垃圾收集系統的工作方式一般是搜索內存中的對象,然後檢查它們的引用表。它計算程序中有多少變量當前正在引用每個對象。若對象的引用數目爲零,它知道此對象不再在使用了,它的內存可以收回。其結果就是,不必像你在C語言所作的那樣,要人工來釋放分配的內存。在C中,釋放內存是一個必要、耗時且易出錯的細節。Java自動而精確的處理此過程,去除了C/C++程序中那種常見的錯誤致因。

6.網絡實現方便

由於今天的嵌入式系統通常都是面向網絡的,採用內置網絡支持的語言節約了在實現網絡協議和通信程序方面耗費的大量時間和努力。在Java中,網絡類包括TCP/IP流和使用TCP及UDP的數據報程序,用於HTTP和URL服務的操作方法,以及錯誤檢查代碼和恢復功能。雖然實現網絡也可能用其他語言,比如C語言,但那些語言要求特別的附件軟件包、DLL,或其他必須由操作系統,或者第三方銷售提供的程序模塊,特別附件通常要求有操作系統或第三方工具的知識,不像Java,有標準的、內置的網絡支持。Java包括網絡包出於必要,因爲設計者不能對一個作爲基礎的操作系統的網絡設施做任何假定,他們必須得包括集成網絡程序庫,以確保Java程序能在所有平臺上工作。

7.可以實現動態配置

動態配置是指系統啓動時的用戶制定配置或重新配置。需載入特殊的硬件配置、網絡參數或在引導期間支持特定用途的一些實用程序的系統,常常使用動態配置。Java以動態捆綁來支持動態配置。當你組成一個程序的各個類文件編譯成字節碼時,在你的類文件之間,或者對JVM包的類(如圖形、網絡以及核心語言支持)引用,還沒有被解決。當JVM載入你的程序時,它動態的載入並捆綁(即鏈接)你的程序引用的所有的類。因此,要改變系統配置,你所需要做的一切就是修正相應的類文件。下一次系統時,JVM自動捆綁新文件到你的程序中,而新的配置將生效執行。

8.可以輕鬆誘捕和處理錯誤

與許多操作系統和程序不同,對嵌入系統而言,重新啓動通常是無法接受的,就像我們都不希望打電話或者看電視時突然有技術性的中斷一樣。這意味着實際上所有嵌入式系統都必須足夠堅實以截取錯誤來防止它們使程序或更糟的是使整個設備崩潰。

程序錯誤的致因很多。相對來說,很少是因爲繼承邏輯錯誤,而大多數程序的崩潰是因爲意外輸入,或者是因爲程序不能調用系統資源來完成某個特定操作造成的。所以,必須能夠預料這些問題,並要能夠誘捕它們,以免引起更大的問題。雖然,能用幾乎任何程序設計語言來誘捕和處理錯誤,不過如果有內置的設施來做這類工作,比如象Java那樣,會有極大的幫助。

在Java中,由拋出(產生)一個異常來提示錯誤。使用專門爲異常處理而設計的語句(關鍵字try、catch、和finally),程序能將其錯誤處理代碼安排到幾個集中區域,try程序塊是程序執行的正常流程。當一個異常發生在try塊(包括該嵌套塊中的各層子程序)中,控制就交給了catch塊。不管是否有異常發生,finally塊中的代碼始終要被執行。未被處理的異常會由調用堆棧自下而上傳播JVM並終止程序。不再需要動手編程,來將錯誤狀態通過幾層函數調用返回。而是,在錯誤發生由檢測錯誤的代碼直接拋出一個異常。這極大地簡化了應用程序中的錯誤處理代碼,進而獲得更好地錯誤處理效果和更堅實可靠的代碼。

9.提供對線程管理的直線支持

大多數操作系統都給一個過程產生和管理多個線程的能力,這些線程彼此獨立地完成不同的任務。但是,很少由程序語言提供對線程管理的直線支持,通常都需要直接調用操作系統功能。Java卻相反,直接在語言提供了產生、管理和協調同步線程地功能。與Java的其他特點一樣,該功能是必要的,因爲設計者不敢確定底層的操作系統是否支持多線程。

開發者越來越多的在程序中使用線程,將其作爲滿足一個程序不能完成的,通常相互無關的一些任務的一種手段。由於Java對線程有內置語言支持,以Java創建多線程較之與其它語言更簡單、更自然。

10.圖形功能強大

JVM包括一個龐大的圖形及窗口支持程序包,稱爲Abstract Windowing Toolkit(AWT)。用AWT,你能在應用程序中快速而輕易地創建精緻而強大的圖形用戶界面。對於需要精細的用戶界面的嵌入系統來說,AWT能節省大量開發時間,從而是產品更快的走向市場。
 
Java語言的諸多優點在某些情況下恰恰可能成爲其不利於在嵌入式系統中得以廣泛應用的絆腳石。因此,還需要不斷完善。在這裏,筆者結合自己的研究,對某些侷限提出一點改進的建議。

 

侷限1:性能較低

    由於解釋Java字節碼比相當的C或C++寫的程序運行起來要慢5到10倍,對一些並非受制於CPU的嵌入系統來說,這一性能缺點不是問題,但是更經常的較慢的速度會導致無法接受的應答時間。

解決方案

   有幾種可能的解決方案可緩解速度慢的問題。

● 使用更快、更強大的處理器,使系統響應時間縮小到可以接受的範圍。不過這個方法將增加每個系統的成本。

● 使用母語Java編譯器來獲得比較好的性能。但這樣做,就放棄了與Java平臺無關的優點,好在大多數嵌入系統都只在一種平臺上運行。

● 在系統上併入一個JIT編譯器,這樣Java類裝入時就被編譯。不過,如果爲接納JIT編譯器而不得不增加額外的內存,這個方法也會增加系統成本。另外,若系統各部分是按需求逐漸添加,則應該控制程序裝入的時機,以使在裝入類進行編譯時產生的暫停不會影響系統的響應時間。

侷限2:垃圾收集的系統開銷過大

   Java中的自動內存分配和垃圾收集性能是很實惠的,但是,從實時系統的角度來看,它的問題恰好就在於它是自動的。當垃圾收集進行時,開發者對系統的控制就受限了。因爲,垃圾收集運行時,它凍結了系統其餘部分的處理。這是因爲它必須要在內存中移動對象,並必須在程序再次運行前,更新所有引用(指向)那些對象的程序變量。垃圾收集需要凍結處理的時間,具體取決於內存量和處理器的速度。很顯然,這對硬實時系統是無法接受的,甚至極端時對軟實時系統也是成問題的。

解決方案

   垃圾收集以三種方式開啓。首先JVM有一個後臺垃圾收集線程,此線程傾向於在它一看見系統有空閒就開始垃圾收集,若有事件想要喚醒另一個線程,後臺垃圾收集就會被該線程佔先,但它不會立刻被佔先,它得更新那些已被移動的對象的所有引用後,才能讓一個線程運行。其次,若JVM沒找到足夠內存來滿足某個內存分配請求,它將啓動一個不會被佔先的垃圾收集,在該操作完成之前,系統的其餘部分被禁止。最後,一個應用程序能通過調用Systev.gc()方法來啓動垃圾收集。所以,如果知道系統暫時不會執行任何時序上關鍵的任務,就可以啓動垃圾收集,避免稍後在更關鍵時段進行收集。

侷限3:JVM的內存開銷過大

   前面我們也論述了許多JVM的內置特點,比如圖形和網絡,它們使得Java程序更快上市。所有這些特點的負面是JVM的內存開銷。因爲JVM是一個整塊(要達到Java的可移植的目的,必須完整的採納),JVM的內存佔用量不能減少。現在的JVM最少需要2MB以上的內存。

解決方案

   如果Java程序也在使用一些消耗內存的功能,由於一個JVM中有那麼多的功能,各個Java應用程序就能寫得小一點。如果建立的是一個從網絡上動態下載並運行多個程序的系統,那麼這將是個很大的優點。但Java仍然不具備可配置性和可伸縮性。

侷限4:缺乏直接硬件接口能力

   Java缺乏直接同硬件接口的能力。JVM僅僅是一個虛擬的機器,一個對硬件的軟件抽象,虛擬機控制與實際硬件的接口,而我們只能和虛擬機打交道。

解決方案

   但這並非是無法逾越的限制,很多C程序使用內嵌彙編來規避性能上的瓶頸,所以Java程序也能使用C來獲得對硬件的直接訪問。

   讓Java和C一起工作有兩種方式。首先,可以使用本地方式,它們是用C/C++或另一種語言寫的,但當調用時,則裝入與JVM同樣的內存空間,運行於同樣的環境。因爲它們被編譯成機器碼,本地方式運行更快並能直接訪問硬件。本地過程與Java代碼之間通過套接來彼此交流,就像網絡中通信端點使用的套接一樣。不過在選擇了混合語言方法後,Java的與平臺無關和安全特點就沒有了。

   另外,可以考慮將前面提到的Java處理器作爲軟件JVM的解釋器部分作爲一種硬件實現方案。Java程序能在這些處理器上直接運行並操縱硬件,要注意的是必需加一些特殊目的的指令給這種語言才能直接與處理器一起工作。

侷限5:語言尚不夠成熟

   從標準的程序設計語言角度來看,Java還很年輕,也很粗糙。如果Java不是由一個小組開發的,也許某些錯誤和疏忽已經被發現和解決了。在Java亮相以後,它立即被用於比原來預期更多的地方。這一切都意味着Java最初的構思和實現,雖然堅實和有用,但在安全、大小和性能幾方面仍感欠缺。

   在其進一步發展中,Sun公司分了三個步驟來促進Java成爲一種通用語言和計算機平臺。首先,用Java編程實現現存的商業和企業的一些功能活動,諸如電子郵件、日曆和字處理程序。其次,把Java提供給企業,使它成爲一種編寫內部應用程序的方法。最後一步,是爲傳統嵌入式設備應用,比如爲移動電話、機頂盒以及打印機定義Java API以及語言功能。

   由此可見,Java的嵌入式應用是排在Sun公司日程的最後的,Sun公司在繼續爲這些用途發展此語言,但對這方面的發展次於桌面及企業用途。按Sun公司的優先順序,很可能還要過一段時間才能解決嵌入式應用中涉及到的一些問題。在此之前,嵌入式系統的編程人員可能不得不迂迴、妥協以及使用第三方解決方案。

   Java開發的編程工具也仍在發展之中。有幾個廠家提供編譯器和開發工具,如Symantec、Microsoft以及Sun公司。Sun不再是JVM和JIT的惟一供應商,其他幾個供應商的產品也很有競爭力。Parasoft公司的Jtest軟件自動爲Java模塊生成檢測案例,而Numega公司的Jcheck爲JVM中的程序行爲提供一定的可見性。不過兩者都只能處理調試程序中的一小部分,而且都是針對桌面系統開發設計的,雖然它們也能用於嵌入開發過程。

   目前Java仍然沒有交叉調試解決方案,即那種傳統上被嵌入系統開發者用來處理目標平臺上程序的方案,所以很可能必須用C/C++來寫程序中針對硬件的部分。不管怎樣,開發者最好用一個C/C++交互調試器來調試那些代碼,並在目標系統上用彈出對話框,保持記錄文件,或其他類技巧來調試Java。(本文作者繫上海大學機電工程及自動化學院博士,E-mail:[email protected]

鏈接:Java背景

   Java語言最初的設計企圖是想用於控制消費性電子產品,比如傳呼機,這些都是典型的嵌入設備。Java的設計者企圖建立一個簡單的、面向對象的、智慧的、已經解譯的、強大的、安全的、架構合理的、可移植的、高性能的、多線程的、動態的語言。爲使Java對開發者有吸引力,Sun公司融合了類似於C語言的語法和結構。然而不管目標訂得如何,Java還是被證明不適合於小型的電子設備,這很大程度上是因爲它太大而且速度太慢。應用Java程序所需要的處理能力和內存量,對這類設備來說太昂貴了。

   話又說回來,Sun公司設計Java時最重要的是平臺無關及網絡集成。一個無須更改就能夠在幾種不同硬件和軟件平臺運行的程序,對網絡環境(在這種環境中用戶希望能夠在辦公室的任何機器上傳、下載和運行程序)來說是一個理想的程序。對想建立通過網絡來通信並利用網上資源的分佈式程序的開發者來說,一種在任何平臺上都有內置的和標準的網絡支持的語言是一個大實惠。

   並且幸運的是,在Java發展的最後階段,對新興的商業化Internet的興趣達到了狂熱的程度。因此Sun公司便藉機鼓吹Java是爲Internet設計的。很多人已經把Java視爲將使Internet功能更上一層樓的工具。雖然Java在網上也從未達到最初理想的那麼普遍,但Java及其“表親”JavaScript(一種由Netscape公司創建的,用於在網頁中寫腳本的類似於Java的語言)早已經是今天大多數商業網站普遍的必備語言了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章