您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java虛擬機內存優化的方法”,在日常操作中,相信很多人在Java虛擬機內存優化的方法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java虛擬機內存優化的方法”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
前面一篇文章介紹了Java虛擬機的體系結構和內存模型,既然提到內存,就不得不說到內存泄露。眾所周知,Java是從C++的基礎上發展而來的,而C++程序的很大的一個問題就是內存泄露難以解決,盡管Java的JVM有一套自己的垃圾回收機制來回收內存,在許多情況下并不需要java程序開發人員操太多的心,但也是存在泄露問題的,只是比C++小一點。比如說,程序中存在被引用但無用的對象:程序引用了該對象,但后續不會或者不能再使用它,那么它占用的內存空間就浪費了。
我們先來看看GC是如何工作的:監控每一個對象的運行狀態,包括對象的申請、引用、被引用、賦值等,當該對象不再被引用時,釋放對象(GC本文的重點,不做過多闡述)。很多Java程序員過分依賴GC,但問題的關鍵是無論JVM的垃圾回收機制做得多好,內存總歸是有限的資源,因此就算GC會為我們完成了大部分的垃圾回收,但適當地注意編碼過程中的內存優化還是很必要的。這樣可以有效的減少GC次數,同時提升內存利用率,***限度地提高程序的效率。
總體而言,Java虛擬機的內存優化應從兩方面著手:Java虛擬機和Java應用程序。前者指根據應用程序的設計通過虛擬機參數控制虛擬機邏輯內存分區的大小以使虛擬機的內存與程序對內存的需求相得益彰;后者指優化程序算法,降低GC負擔,提高GC回收成功率。
通過參數優化虛擬機內存的參數如下所示:
◆ Xms
初始Heap大小
◆ Xmx
java heap***值
◆ Xmn
young generation的heap大小
◆ Xss
每個線程的Stack大小
上面是三個比較常用的參數,還有一些:
◆ XX:MinHeapFreeRatio=40
Minimum percentage of heap free after GC to avoid expansion.
◆ XX:MaxHeapFreeRatio=70
Maximum percentage of heap free after GC to avoid shrinking.
◆ XX:NewRatio=2
Ratio of new/old generation sizes. [Sparc -client:8; x86 -server:8; x86 -client:12.]-client:8 (1.3.1+), x86:12]
◆ XX:NewSize=2.125m
Default size of new generation (in bytes) [5.0 and newer: 64 bit VMs are scaled 30% larger; x86:1m; x86, 5.0 and older: 640k]
◆ XX:MaxNewSize=
Maximum size of new generation (in bytes). Since 1.4, MaxNewSize is computed as a function of NewRatio.
◆ XX:SurvivorRatio=25
Ratio of eden/survivor space size [Solaris amd64: 6; Sparc in 1.3.1: 25; other Solaris platforms in 5.0 and earlier: 32]
◆ XX:PermSize=
Initial size of permanent generation
◆ XX:MaxPermSize=64m
Size of the Permanent Generation. [5.0 and newer: 64 bit VMs are scaled 30% larger; 1.4 amd64: 96m; 1.3.1 -client: 32m.]
下面所說通過優化程序算法來提高內存利用率,并降低內存風險,完全是經驗之談,僅供參考,如有不妥,請指正,謝謝!
1.盡早釋放無用對象的引用(XX = null;)
看一段代碼:
public List<PageData> parse(HtmlPage page) { List<PageData> list = null; try { List valueList = page.getByXPath(config.getContentXpath()); if (valueList == null || valueList.isEmpty()) { return list; } //需要時才創建對象,節省內存,提高效率 list = new ArrayList<PageData>(); PageData pageData = new PageData(); StringBuilder value = new StringBuilder(); for (int i = 0; i < valueList.size(); i++) { HtmlElement content = (HtmlElement) valueList.get(i); DomNodeList<HtmlElement> imgs = content.getElementsByTagName("img"); if (imgs != null && !imgs.isEmpty()) { for (HtmlElement img : imgs) { try { HtmlImage image = (HtmlImage) img; String path = image.getSrcAttribute(); String format = path.substring(path.lastIndexOf("."), path.length()); String localPath = "D:/images/" + MD5Helper.md5(path).replace("\\", ",").replace("/", ",") + format; File localFile = new File(localPath); if (!localFile.exists()) { localFile.createNewFile(); image.saveAs(localFile); } image.setAttribute("src", "file:///" + localPath); localFile = null; image = null; img = null; } catch (Exception e) { } } //這個對象以后不會在使用了,清除對其的引用,等同于提前告知GC,該對象可以回收了 imgs = null; } String text = content.asXml(); value.append(text).append("<br/>"); valueList=null; content = null; text = null; } pageData.setContent(value.toString()); pageData.setCharset(page.getPageEncoding()); list.add(pageData); //這里 pageData=null; 是沒用的,因為list仍然持有該對象的引用,GC不會回收它 value=null; //這里可不能 list=null; 因為list是方法的返回值,否則你從該方法中得到的返回值永遠為空,而且這種錯誤不易被發現、排除 } catch (Exception e) { } return list; }
2.謹慎使用集合數據類型,如數組,樹,圖,鏈表等數據結構,這些數據結構對GC來說回收更復雜。
3.避免顯式申請數組空間,不得不顯式申請時,盡量準確估計其合理值。
4.盡量避免在類的默認構造器中創建、初始化大量的對象,防止在調用其自類的構造器時造成不必要的內存資源浪費
5.盡量避免強制系統做垃圾內存的回收,增長系統做垃圾回收的最終時間
6.盡量做遠程方法調用類應用開發時使用瞬間值變量,除非遠程調用端需要獲取該瞬間值變量的值。
7.盡量在合適的場景下使用對象池技術以提高系統性能
到此,關于“Java虛擬機內存優化的方法”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。