王曉亮
摘要:Java虛擬機(jī)在運(yùn)行Java應(yīng)用程序的查詢操作時(shí),存在由于查詢結(jié)果數(shù)據(jù)量大和查詢并發(fā)性高而出現(xiàn)系統(tǒng)不穩(wěn)定的問題。提出了一種JVM內(nèi)存使用優(yōu)化方案:恒定使用JVM內(nèi)存,能夠在不提高硬件成本的情況下,保證系統(tǒng)連續(xù)穩(wěn)定地運(yùn)行。
Abstract: The system instability problem appears on large amount of query result data volume and high query concurrency when JVM is running a Java application query operation. A JVM memory use optimization scheme is proposed: use the JVM memory constantly, it can ensure system continuous steady operation without the increase the hardware cost.
關(guān)鍵詞:JAVA;JAVA虛擬機(jī);內(nèi)存使用優(yōu)化;穩(wěn)定性
Key words: JAVA;JVM;use optimization of memory;stability
中圖分類號(hào):TP31 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1006-4311(2017)21-0221-02
0 引言
基于Java的應(yīng)用程序?qū)嶋H運(yùn)行過程中,因?yàn)槠湔Z言自身所具備的特點(diǎn)以及虛擬機(jī)等方面的影響,其相應(yīng)客戶端硬件配置的實(shí)際要求要比VC++和VB語言編寫的程序高出許多。盡管Java 2對(duì)于JDK虛擬機(jī)解釋器實(shí)施了優(yōu)化處理,但并不能夠達(dá)到是用戶的某些要求。所以,Java程序的開發(fā)人員在對(duì)程序代碼優(yōu)化過程中,比較注重它的運(yùn)行性能。其實(shí),Java運(yùn)行程序能夠從依靠其他方面進(jìn)行相應(yīng)的優(yōu)化,即對(duì)程序所占用內(nèi)存空間進(jìn)行管理優(yōu)化。很多功能復(fù)雜的Java應(yīng)用程序在運(yùn)行時(shí)因?yàn)橄到y(tǒng)頻繁針對(duì)內(nèi)存進(jìn)行存儲(chǔ)文件操作,所以極大的降低了軟件實(shí)際運(yùn)行性能。程序中存在的內(nèi)存漏洞造成了程序通過操作系統(tǒng)消耗內(nèi)存,而沒有及時(shí)進(jìn)行對(duì)內(nèi)存空間的復(fù)用和釋放,致使程序消耗相應(yīng)的內(nèi)存空間越來越大。
衡量Java程序內(nèi)存行為的一項(xiàng)重要指標(biāo)就是內(nèi)存分配速率,它的含義是指在單位時(shí)間內(nèi)分配給運(yùn)行程序內(nèi)存容量。在計(jì)算該指標(biāo)數(shù)據(jù)時(shí)一般情況下不包括收集內(nèi)存垃圾所占用的時(shí)間。一個(gè)程序在其運(yùn)行的時(shí)候會(huì)連續(xù)產(chǎn)生多個(gè)對(duì)象,這就同時(shí)需要有相應(yīng)的回收垃圾對(duì)象的內(nèi)存垃圾回收程序,而內(nèi)存垃圾產(chǎn)生的速度快慢也對(duì)Java程序的內(nèi)存運(yùn)行效率有很大的影響。Java程序運(yùn)行的基本流程是首先分配程序運(yùn)行所需的內(nèi)存,當(dāng)在程序運(yùn)行過程中出現(xiàn)堆空間不夠這種情況時(shí),就會(huì)進(jìn)行垃圾對(duì)象的回收。當(dāng)垃圾對(duì)象回收完成后,當(dāng)前可用內(nèi)存容量就會(huì)恢復(fù)到一個(gè)數(shù)量,這個(gè)數(shù)量的內(nèi)存容量是當(dāng)前正在運(yùn)行的Java程序存儲(chǔ)其運(yùn)行所需的數(shù)據(jù)結(jié)構(gòu)所需要占用的內(nèi)容容量,也是其工作時(shí)需要占用的基本內(nèi)容空間,該內(nèi)存空間可以稱為工作內(nèi)存。工作內(nèi)存空間數(shù)量的變化同時(shí)也能夠反映出來Java程序運(yùn)行所需的數(shù)據(jù)結(jié)構(gòu)所占用的內(nèi)存容量的變化情況。
盡管現(xiàn)在內(nèi)存的性價(jià)比越來越高,但OS管理內(nèi)存的空間不是無限大的,JVM對(duì)內(nèi)存的管理能力也是有限的。由SUN公司提供的JVM內(nèi)存使用空間資料如表1所示。在硬件配置一定的情況下,如果JVM能夠巧妙的使用有限的內(nèi)存,則可以使系統(tǒng)避免因內(nèi)存overflow而出現(xiàn)當(dāng)機(jī)的情況。
■
因此,對(duì)JVM的內(nèi)存使用優(yōu)化技術(shù)進(jìn)行研究將具有重要的價(jià)值。下面針對(duì)在某公司的業(yè)務(wù)查詢中出現(xiàn)的問題進(jìn)行分析研究,并給出具體的解決方案。
1 JVM內(nèi)存使用未優(yōu)化出現(xiàn)的問題
網(wǎng)絡(luò)計(jì)算機(jī)(Network Computer:NC)在教育、電信、保險(xiǎn)、金融等行業(yè)的市場(chǎng)表現(xiàn)良好,已創(chuàng)造出相當(dāng)可觀的經(jīng)濟(jì)效益和社會(huì)價(jià)值,具有很大的發(fā)展?jié)摿ΑS芍С諮ava的三層構(gòu)架實(shí)現(xiàn)的NC的軟件設(shè)計(jì)如圖1所示,這種結(jié)構(gòu)已成為NC發(fā)展的必然趨勢(shì)[2]。
NC系統(tǒng)軟件包括兩大部分:運(yùn)行在NC上的NCOS和運(yùn)行在應(yīng)用服務(wù)器上的NC Server。由圖1可以看出Java虛擬機(jī)(Java Virtual Machine-JVM)是兩大部分的主要組件,它對(duì)內(nèi)存的管理能力將影響Java應(yīng)用程序執(zhí)行的具體效果以及NC中其他服務(wù)的性能表現(xiàn)。
1.1 當(dāng)機(jī)的出現(xiàn)
某公司管理系統(tǒng)采用結(jié)構(gòu)情況:在數(shù)據(jù)庫服務(wù)器端使用的是Sybase12.5,應(yīng)用服務(wù)器使用的是Web Logic8,網(wǎng)絡(luò)操作系統(tǒng)采用的是Linux。系統(tǒng)起初運(yùn)行時(shí)一切正常,因?yàn)樵摴臼且患沂〖?jí)公司,在各地市都有分支機(jī)構(gòu),所以隨著業(yè)務(wù)量的增加,數(shù)據(jù)庫也越來越大。在一次月終總結(jié)查詢時(shí),需要查詢結(jié)果記錄量很大,這時(shí)出現(xiàn)了服務(wù)器停止響應(yīng)的當(dāng)機(jī)故障。
1.2 對(duì)出現(xiàn)當(dāng)機(jī)問題的分析
Java程序在運(yùn)行時(shí)處理內(nèi)存短缺問題方面的解決方案通常是使用Java語言提供的無用內(nèi)存單元回收功能(又稱為垃圾回收功能)。程序在運(yùn)行過程中需要構(gòu)造對(duì)象實(shí)例,這時(shí)程序解釋器向操作系統(tǒng)發(fā)出內(nèi)存申請(qǐng),操作系統(tǒng)從內(nèi)存堆中預(yù)留一塊內(nèi)存空間,并使用這個(gè)空間來存儲(chǔ)對(duì)象實(shí)例變量的值。在程序運(yùn)行過程中對(duì)象、變量和方法的構(gòu)造都會(huì)占用一定的內(nèi)存空間。而某些變量或?qū)ο笤谕瓿闪艘淮位驇状握{(diào)用后不會(huì)繼續(xù)被程序所使用?!盁o用單元回收”這一概念的含義就是程序中一個(gè)實(shí)用線程或進(jìn)程跟蹤程序,對(duì)那些不再被使用的內(nèi)存單元進(jìn)行清理,并將釋放后的內(nèi)存單元?dú)w還操作系統(tǒng)或程序以便復(fù)用。但是此進(jìn)程跟蹤程序只有其內(nèi)存不足時(shí),才開始對(duì)“無用單元”實(shí)施回收。倘若其內(nèi)存存在著大量的數(shù)據(jù),但其“無用單元”得不到一定的釋放時(shí),則會(huì)導(dǎo)致內(nèi)存不足的現(xiàn)象發(fā)生。進(jìn)而致使系統(tǒng)在工作時(shí)意外中斷等一系列情況產(chǎn)生[3]。
對(duì)于上面出現(xiàn)的問題,我們作了這樣的研究分析:
①由于查詢結(jié)果的記錄首先要讀入JVM內(nèi)存,所以一個(gè)查詢操作就有可能有大量的數(shù)據(jù)占用了JVM內(nèi)存。
②在月終按分類進(jìn)行金額的匯總時(shí),在各個(gè)分支機(jī)構(gòu)點(diǎn)都有這樣的操作,此時(shí)查詢操作的并發(fā)性高。大量的查詢結(jié)果記錄同時(shí)占用JVM所管理的內(nèi)存。排除其它硬件問題,出現(xiàn)系統(tǒng)中斷情況的一種可能是JVM使用的內(nèi)存不足。
2 JVM內(nèi)存使用優(yōu)化方案
系統(tǒng)在查詢結(jié)果數(shù)據(jù)量小且并發(fā)查詢少的情況下,系統(tǒng)運(yùn)行是穩(wěn)定的;只有當(dāng)數(shù)據(jù)庫中記錄總數(shù)增多,查詢的結(jié)果也越來越龐大時(shí),才會(huì)出現(xiàn)上面見到的現(xiàn)象。所以,如果各個(gè)進(jìn)程合理使用JVM內(nèi)存,而不是長(zhǎng)時(shí)間大量占用內(nèi)存,可以解決由內(nèi)存短缺而造成的系統(tǒng)中斷問題[4]。
依據(jù)以上對(duì)JVM使用內(nèi)存的分析,提出解決此問題的一種方案:恒定使用Java虛擬機(jī)內(nèi)存。
2.1 優(yōu)化思路
恒定使用Java虛擬機(jī)內(nèi)存方案的優(yōu)化思路是:客戶端借由應(yīng)用服務(wù)器進(jìn)而查詢所對(duì)應(yīng)的數(shù)據(jù)庫時(shí),并不是把其所查出的數(shù)據(jù)記錄一次性讀入JVM內(nèi)存,進(jìn)而再返回客戶端,實(shí)際上是將所查詢出來的結(jié)果組織為查詢結(jié)果文件,先將其暫存于應(yīng)用服務(wù)器相應(yīng)硬盤上,然后將壓縮的“查詢結(jié)果文件”傳送到客戶端。
2.2 生成查詢結(jié)果文件
將從數(shù)據(jù)庫所查得出的所有數(shù)據(jù),組織為一個(gè)查詢結(jié)果文件,其實(shí)際操作如下:每次從數(shù)據(jù)庫服務(wù)器讀取MAX行(該數(shù)據(jù)是一個(gè)試驗(yàn)值,具體值依賴于應(yīng)用服務(wù)器性能配置和并發(fā)訪問量)數(shù)據(jù)后,在JVM內(nèi)存中經(jīng)過簡(jiǎn)單加工,寫入“查詢結(jié)果文件”,直至得出全部的結(jié)果。所得出的查詢結(jié)果文件是以壓縮形式發(fā)出的,可以使其文件變小,進(jìn)而有效減少客戶端讀取此文件時(shí)的所實(shí)際消耗的時(shí)間??偠灾疃嘀挥蠱AX行的記錄占用JVM內(nèi)存,而其它已查到的記錄陸續(xù)寫入了硬盤,這就保證了JVM內(nèi)存使用的大小是“恒定”的。對(duì)于暫存于硬盤上的壓縮文件可以設(shè)置定期刪除,避免占用大量應(yīng)用服務(wù)器硬盤空間[5]。
該步驟主要完成的工作流程:每次首先從數(shù)據(jù)庫查詢記錄行數(shù)的最大值,建立與數(shù)據(jù)庫的連接,執(zhí)行相應(yīng)的SQL查詢語句,形成查詢RS結(jié)果集合。從數(shù)據(jù)庫服務(wù)器查詢數(shù)據(jù),并將查詢結(jié)果形成壓縮文件。打開壓縮文件輸出流,從RS中讀取數(shù)據(jù),緩存到buffer內(nèi)存對(duì)象,根據(jù)需要對(duì)數(shù)據(jù)進(jìn)行處理,當(dāng)數(shù)量達(dá)到預(yù)定的閥值時(shí),寫入壓縮文件,釋放內(nèi)存,同時(shí)將計(jì)數(shù)器清零。向客戶端返回查詢結(jié)果文件的地址,輸出剩余數(shù)據(jù),最后關(guān)閉數(shù)據(jù)庫文件。
2.3 查詢結(jié)果的讀取
暫存于應(yīng)用服務(wù)器上查詢結(jié)果壓縮文件,可直接通過http協(xié)議傳輸給客戶端,在客戶端僅僅需要將壓縮文件進(jìn)行解壓操作,就能夠得到所需結(jié)果。流程包括:首先從從應(yīng)用服務(wù)器端查詢獲取結(jié)果壓縮文件到客戶端,然后在客戶端完成壓縮文件的解壓縮,并將結(jié)果數(shù)據(jù)展示出來。
3 結(jié)束語
提出的優(yōu)化方案主要有以下3個(gè)特點(diǎn):
①每次從數(shù)據(jù)庫服務(wù)器讀取預(yù)定的數(shù)據(jù)行到JVM進(jìn)行數(shù)據(jù)加工,然后寫入文件系統(tǒng),從而避免了由于數(shù)據(jù)量太大而導(dǎo)致JVM內(nèi)存急劇消耗。
②生成的查詢結(jié)果文件通過壓縮文件的方式傳給客戶,減小了文件大小,縮短了文件傳輸時(shí)間。
③在系統(tǒng)硬件資源開銷不增加的情況下,保證了大數(shù)據(jù)量查詢時(shí)系統(tǒng)的穩(wěn)定性。
優(yōu)化方案經(jīng)過實(shí)際應(yīng)用,被證明是一種解決由JVM內(nèi)存短缺引起系統(tǒng)不穩(wěn)定的切實(shí)可行的方法。
參考文獻(xiàn):
[1]VENNERS B. Inside the Java Virtual Machine[M]. New York McCraw-Hill,2000:27-98.
[2]LINDOLM T YELLIN F. The Java Virtual Machine specification [M]. Boston, MA: Addison Wesley,1999, 21(104).
[3]徐鵬,王克宏.Java程序內(nèi)存空間優(yōu)化策略的研究[J].計(jì)算機(jī)科學(xué),2002,29(4):24-27.
[4]曹曉鋼,蔣靖譯.Bill Venners.深入Java虛擬機(jī)[M].北京:機(jī)械工業(yè)出版社,2003.
[5]楊麗潔.基于Linux網(wǎng)絡(luò)計(jì)算機(jī)Java虛擬機(jī)的性能優(yōu)化[J].計(jì)算機(jī)工程,2007,33(3):53-55.