摘 要:Java虛擬機在運行應(yīng)用程序查詢操作時,存在由于查詢結(jié)果數(shù)據(jù)量大和查詢并發(fā)性高而出現(xiàn)系統(tǒng)不穩(wěn)定的問題。本文實現(xiàn)了一種JVM內(nèi)存使用優(yōu)化方案:恒定使用JVM內(nèi)存,在硬件成本不提高的情況下,保證了系統(tǒng)穩(wěn)定運行。
關(guān)鍵詞:JAVA;JAVA虛擬機;內(nèi)存使用優(yōu)化;穩(wěn)定性
中圖分類號:TP316.8 文獻標(biāo)志碼:A
An Optimization Strategy Based on The Memory Usage’s in JVM
Zhang Hong-mei
(The Computer Department of Vocation College of Bin ZhouBin Zhou256603 China)
Abstract:The unsteady question appears in java virtual computer’s query because of a great of query’records and eruptions. The text gives an excellent project of usage memory in JVM:Keeps constant in usage memory of JVM. The stability of the system is promised under that the cost of hardware does not rise.
Key Words:JAVA; JVM; Memory Usage’s Optimization;Stability
盡管現(xiàn)在內(nèi)存的性價比越來越高,但操作系統(tǒng)管理內(nèi)存的空間不是無限大的,Java虛擬機(JVM)對內(nèi)存的管理能力也是有限的[1]。在硬件配置一定的情況下,如果JVM能夠巧妙的使用有限的內(nèi)存,則可以使系統(tǒng)避免因內(nèi)存overflow而出現(xiàn)宕機的情況。
因此,對JVM的內(nèi)存使用優(yōu)化技術(shù)進行研究將具有重要的價值。下面針對在保險公司的業(yè)務(wù)查詢中曾碰到的問題進行分析研究,并給出了具體的解決方案。
1 JVM內(nèi)存未優(yōu)化使用出現(xiàn)的問題
網(wǎng)絡(luò)計算機(Network Computer——NC)在金融、保險、教育、電信等行業(yè)的市場表現(xiàn)良好,已創(chuàng)造出相當(dāng)可觀的經(jīng)濟效益和社會價值,具有很大的發(fā)展?jié)摿?。由支持Java的三層構(gòu)架[2]實現(xiàn)的NC的軟件設(shè)計如圖1所示,這種結(jié)構(gòu)已成為NC發(fā)展的必然趨勢。
NC系統(tǒng)軟件包括兩大部分:運行在NC上的NCOS和運行在應(yīng)用服務(wù)器上的NC Server。由圖1可以看出Java虛擬機是兩大部分的主要組件,它對內(nèi)存的管理能力將影響Java應(yīng)用程序執(zhí)行的具體效果以及NC中其他服務(wù)的性能表現(xiàn)。
1.1 宕機的出現(xiàn)
陽光財產(chǎn)保險公司的管理系統(tǒng)即采用此結(jié)構(gòu):在數(shù)據(jù)庫服務(wù)器端使用的是Sybase12.5;應(yīng)用服務(wù)器使用的是WebLogic8;網(wǎng)絡(luò)操作系統(tǒng)采用的是Linux。系統(tǒng)起初運行時一切正常。但隨著業(yè)務(wù)量的增加,數(shù)據(jù)庫也越來越大。在一次月終總結(jié)查詢時,出現(xiàn)了問題——按險種進行本地投保金額統(tǒng)計,出現(xiàn)了服務(wù)器停止響應(yīng),即宕機(shut down)。
1.2 對出現(xiàn)宕機現(xiàn)象的分析
Java程序在運行過程中所進行的操作是通過實例化的對象調(diào)用成員方法實現(xiàn)的,當(dāng)需要構(gòu)造對象實例時,程序解釋器向操作系統(tǒng)發(fā)出內(nèi)存申請,操作系統(tǒng)從內(nèi)存堆中預(yù)留一塊內(nèi)存空間,并使用這個空間來存儲對象實例變量的值。“無用單元回收”是程序中的一個實用線程或進程跟蹤程序,對那些不再被使用的內(nèi)存單元進行清理,并將釋放后的內(nèi)存單元歸還操作系統(tǒng)以便復(fù)用。但是此進程跟蹤程序只有在內(nèi)存短缺時,才對“無用單元”進行回收[3]。如果有大量的數(shù)據(jù)占用了內(nèi)存空間,而無更多的“無用單元”進行釋放,此時再為實例化對象申請空間時,便出現(xiàn)內(nèi)存不足的問題,即可能出現(xiàn)由于系統(tǒng)內(nèi)存不足而導(dǎo)致系統(tǒng)運行意外中斷等例外情況的發(fā)生。
對于結(jié)果數(shù)據(jù)量大的查詢而出現(xiàn)的宕機問題,作了這樣的分析研究:
1)由于查詢結(jié)果的記錄首先要讀入JVM內(nèi)存,所以一個查詢操作就可能有大量的數(shù)據(jù)占用了JVM內(nèi)存。
2)在月終按某種險種進行金額匯總時,在各個分枝機構(gòu)點都有這樣的操作,此時查詢操作的并發(fā)性高。大量的查詢結(jié)果記錄同時占用NC Server JVM所管理的內(nèi)存。
排除其它硬件問題,出現(xiàn)系統(tǒng)shut down情況的一種最大可能是JVM使用的內(nèi)存不足。
2 JVM內(nèi)存使用優(yōu)化方案
在查詢結(jié)果數(shù)據(jù)量小且并發(fā)少的情況下,系統(tǒng)運行是穩(wěn)定的,只有當(dāng)數(shù)據(jù)庫中記錄總數(shù)增多,查詢的結(jié)果也越來越龐大時,才會出現(xiàn)上面見到的現(xiàn)象。所以,如果各個進程合理使用JVM內(nèi)存,而不是長時間大量占用內(nèi)存,可以解決由內(nèi)存短缺而造成的系統(tǒng)中斷問題。
依據(jù)以上對JVM使用內(nèi)存的分析,作者經(jīng)較長時間的研究與實踐,最終得出解決此問題的一種方案——恒定使用Java虛擬機內(nèi)存。
2.1 優(yōu)化思想
恒定使用Java虛擬機內(nèi)存的思想是:客戶端通過應(yīng)用服務(wù)器對數(shù)據(jù)庫進行查詢時,不再將在數(shù)據(jù)庫中查詢到的所有記錄一次性讀入JVM內(nèi)存,然后再返回給客戶端,而是將查詢得到的部分記錄占用恒定的內(nèi)存大小,逐步組織為查詢結(jié)果文件,先暫存于應(yīng)用服務(wù)器的硬盤上,然后將壓縮的“查詢結(jié)果文件”傳輸給客戶端。
2.2 生成查詢結(jié)果文件
優(yōu)化從數(shù)據(jù)庫中查詢到的數(shù)據(jù),組織為查詢結(jié)果文件,具體操作是:每次從數(shù)據(jù)庫服務(wù)器讀取MAX行(譬如2000行)數(shù)據(jù)后,在JVM內(nèi)存中經(jīng)過簡單加工,寫入“查詢結(jié)果文件”,直到所有的結(jié)果已查出。所生成的查詢結(jié)果文件是壓縮的,目的是減少文件的大小,縮短客戶端讀取此文件時的傳輸時間。以上操作的結(jié)果是,最多只有MAX行的記錄占用JVM內(nèi)存,而其它已查到的記錄已陸續(xù)寫入了硬盤,這就保證了JVM內(nèi)存使用的大小是“恒定”的。生成查詢結(jié)果文件的主要代碼如下:
//1 取得數(shù)據(jù)庫聯(lián)接,執(zhí)行查詢SQL語句,得到結(jié)果集 ResultSet
Connection connection=...
Statement stmt=onnection.createStatement();
ResultSetrs=stmt.executeQuery(sql);
//2從數(shù)據(jù)庫服務(wù)器讀取數(shù)據(jù),寫入壓縮文件
//2.1打開壓縮文件輸出流
FileOutputStreamfileOutputStream=new FileOutputStream(fileName);
GZIPOutputStream zipOutputStream=new GZIPOutputStream(fileOutputStream);
//2.2從rs中讀取數(shù)據(jù),緩存到內(nèi)存對象buffer while (rs.next()) {
//根據(jù)需要對數(shù)據(jù)加工
buffer.append(″一行數(shù)據(jù)″);
count++;
//當(dāng)達到預(yù)定的閥值(_VALVE)時,寫入壓縮文件,釋放內(nèi)存。
if (count== _VALVE) {
// 2.2.1 寫文件
byte[] bys=
buffer.toString().getBytes(″UTF-8″);
zipOutputStream.write(bys, 0, bys.length);
//2.2.2釋放內(nèi)存,計數(shù)器歸零
… } }
2.3 查詢結(jié)果的讀取
暫存于應(yīng)用服務(wù)器上的查詢結(jié)果壓縮文件,可直接通過http協(xié)議傳輸給客戶端,在客戶端只要解開壓縮文件,即可顯示所查到的結(jié)果。其主要代碼如下:
//1從應(yīng)用服務(wù)器端獲取查詢結(jié)果文件
URL url=new URL(urlString);
InputStream in=url.openStream();
GZIPInputStream zipInputStream=new
GZIPInputStream(in);
InputStreamReader inputStreamReader=new InputStreamReader(zipInputStream,“UTF-8”);
BufferedReader bufReader=new
BufferedReader(inputStreamReader);
//2讀取文件內(nèi)容,展示數(shù)據(jù)
}
3 結(jié)束語
本文的優(yōu)化方案主要有以下3個特點:
1)每次從數(shù)據(jù)庫服務(wù)器讀取預(yù)定的數(shù)據(jù)行到JVM內(nèi)存進行數(shù)據(jù)加工,然后寫入文件系統(tǒng),從而避免了由于數(shù)據(jù)量太大而導(dǎo)致JVM內(nèi)存急劇消耗。
2)生成的查詢結(jié)果文件通過壓縮文件的方式傳給客戶,減小了文件大小,縮短了文件傳輸時間。
3)在系統(tǒng)硬件資源開銷不增加的情況下,保證了大數(shù)據(jù)量查詢時系統(tǒng)運行的穩(wěn)定性。
本方案在陽光財產(chǎn)保險公司計算機管理系統(tǒng)中應(yīng)用,被證明是一種解決由JVM內(nèi)存短缺引起系統(tǒng)不穩(wěn)定的切實可行的方法。
參考文獻
[1]朱喜福.Java程序設(shè)計[M].北京:人民郵電出版社,2006.
[2]HenryXie.J2EE經(jīng)典實例詳解[M].北京:人民郵電出版社,2003.
[3]王克宏,郝建文.Java 技術(shù)教程[M].北京:清華大學(xué)出版社,2002.
[4]呂鳳翥.Java語言程序設(shè)[M].北京:清華大學(xué)出版社,2007.
[5]李超燕.數(shù)據(jù)庫原理及應(yīng)用教程[M].北京:科學(xué)出版社,2004.