這篇文章將為大家詳細(xì)講解有關(guān)Java項(xiàng)目中出現(xiàn)內(nèi)存溢出的原因有哪些,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括弓長嶺網(wǎng)站建設(shè)、弓長嶺網(wǎng)站制作、弓長嶺網(wǎng)頁制作以及弓長嶺網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,弓長嶺網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到弓長嶺省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!什么是JAVA內(nèi)存泄漏?
簡單地說,Java內(nèi)存泄漏是指對(duì)象不再被應(yīng)用程序使用,而是在工作內(nèi)存中處于活動(dòng)狀態(tài)。
在Java和大多數(shù)其他編程語言中,垃圾收集器的任務(wù)是刪除不再被應(yīng)用程序引用的對(duì)象。如果不選中,這些對(duì)象將繼續(xù)消耗系統(tǒng)內(nèi)存,并最終導(dǎo)致崩潰。有時(shí)java內(nèi)存泄漏崩潰不會(huì)輸出錯(cuò)誤,但通常錯(cuò)誤會(huì)以java.lang.OutOfMemoryError
當(dāng)未被引用的對(duì)象被歸類為引用對(duì)象時(shí),就會(huì)導(dǎo)致Java內(nèi)存泄漏。這會(huì)阻止垃圾回收器清除內(nèi)存,導(dǎo)致內(nèi)存最終耗盡并崩潰。
在內(nèi)存中,對(duì)象可以有兩種狀態(tài),未引用和已引用。被引用的對(duì)象仍然具有到Java應(yīng)用程序的活動(dòng)連接,而未被引用的對(duì)象則沒有。垃圾回收器的任務(wù)是查找和標(biāo)識(shí)未引用的對(duì)象并將其刪除。
垃圾回收器不會(huì)清理似乎被引用或正在使用的對(duì)象。Java內(nèi)存泄漏發(fā)生在未引用的對(duì)象重疊時(shí),這些對(duì)象似乎仍在使用中。
有幾種方法可以檢查你的代碼,看看它是否發(fā)生了內(nèi)存泄漏。識(shí)別泄漏的最簡單方法是查找java.lang.OutOfMemoryError錯(cuò)誤日志中的事件。如果列出了此事件,您將能夠提取有關(guān)Java的哪些部分導(dǎo)致了這種情況的進(jìn)一步詳細(xì)信息。
您經(jīng)常會(huì)發(fā)現(xiàn)有關(guān)Java堆空間的詳細(xì)信息。這可能意味著內(nèi)存泄漏,資源無法分配,或者堆大小設(shè)置得太低。
通常也會(huì)發(fā)現(xiàn)標(biāo)記為PermGen空間的錯(cuò)誤。在大多數(shù)情況下,這不是內(nèi)存泄漏,而是需要擴(kuò)展的分配空間。永久生成空間用于存儲(chǔ)類對(duì)象,如果不擴(kuò)展,則可以填充。
并不是所有的Java內(nèi)存泄漏都是相同的,有些漏洞可以比其他漏洞更容易預(yù)防。讓我們來看看Java內(nèi)存泄漏的一些最常見的原因。
最常見的內(nèi)存泄漏類型之一是Java中的對(duì)象隨著時(shí)間的推移而創(chuàng)建,但從未釋放。提高性能和防止內(nèi)存泄漏的一個(gè)簡單方法是檢查代碼中靜態(tài)字段的使用情況。
當(dāng)您將Java中的任何對(duì)象設(shè)置為靜態(tài)時(shí),它會(huì)自動(dòng)將該對(duì)象的生命周期附加到JVM本身,因此垃圾收集器從不清除它。正如您可以想象的那樣,如果您有許多大對(duì)象被設(shè)置為靜態(tài)的,這會(huì)在您的代碼中造成相當(dāng)大的問題。
一定要檢查static和collections的所有用法。這兩者都是導(dǎo)致Java內(nèi)存泄漏和意外占用內(nèi)存的最常見原因。
Java內(nèi)存泄漏的另一個(gè)常見原因是存在未關(guān)閉的連接。代碼中保持連接打開而不關(guān)閉連接的任何部分都可能導(dǎo)致內(nèi)存過度使用。未閉合連接最常見的罪魁禍?zhǔn)资莌ttp調(diào)用、stream流、FTP站點(diǎn)和數(shù)據(jù)庫訪問。
當(dāng)保持打開狀態(tài)時(shí),連接會(huì)迅速導(dǎo)致堆內(nèi)存膨脹,并最終導(dǎo)致應(yīng)用程序崩潰。若要解決此問題,請始終確保在代碼中指定了關(guān)閉連接的時(shí)間。
就像未關(guān)閉的連接一樣,未關(guān)閉的流會(huì)導(dǎo)致非常類似的內(nèi)存泄漏和資源問題。如果未選中,則打開的流將增加堆內(nèi)存使用量,以達(dá)到臨界級(jí)別,并最終崩潰。在舊版本的Java中,流必須手動(dòng)關(guān)閉,但是現(xiàn)在使用try with resources語句,這可以自動(dòng)實(shí)現(xiàn)。
雖然尋找這些具體的例子可能會(huì)有所幫助,但每個(gè)程序的編碼都是不同的,需要采用不同的方法。如果您要手動(dòng)查看代碼,啟用詳細(xì)的垃圾收集可以幫助您更好地了解哪些內(nèi)容正在被收集,哪些內(nèi)容沒有被收集。
添加-verbose:gc參數(shù)到配置將準(zhǔn)確地輸出垃圾收集工具正在執(zhí)行的操作,并讓您深入了解可能需要修改的內(nèi)容。這是一個(gè)簡單的技巧,但仍然需要你的時(shí)間和精力來篩選結(jié)果。
對(duì)代碼進(jìn)行可靠的審核還可以發(fā)現(xiàn)阻礙性能或?qū)е聝?nèi)存泄漏的潛在問題。雖然這看起來很費(fèi)時(shí),但這通常是處理所有代碼的很好實(shí)踐,并有助于避免嚴(yán)重的麻煩。
最后,為了更快地堵住內(nèi)存泄漏,可以考慮使用Java分析器。探查器允許您監(jiān)視特定的JVM參數(shù),例如對(duì)象創(chuàng)建和垃圾回收。探查器甚至比詳細(xì)模式更進(jìn)一步,可以幫助突出顯示需要數(shù)小時(shí)手動(dòng)跟蹤的內(nèi)存和資源問題。
您可以使用諸如YourKit或JProfiler這樣的Java探查器,不僅可以幫助您發(fā)現(xiàn)Java代碼中的內(nèi)存泄漏,還可以確定優(yōu)化和改進(jìn)的機(jī)會(huì)。YourKit和JProfiler都有助于刪減不必要的代碼并識(shí)別應(yīng)用程序中的冗余。雖然這兩個(gè)示例都不會(huì)導(dǎo)致內(nèi)存泄漏,但它們會(huì)影響代碼的性能。
JAVA Profiler可以提供以下功能:
創(chuàng)建的所有對(duì)象
所有方法的CPU時(shí)間
執(zhí)行期間創(chuàng)建的對(duì)象
從內(nèi)存中刪除的對(duì)象
垃圾收集信息
但是,使用一個(gè)好的Java分析器只是成功的一半;您還需要監(jiān)視應(yīng)用程序的運(yùn)行狀況,因?yàn)樗鼤?huì)隨著時(shí)間的推移而變化。為此,您需要將Java分析器與一個(gè)著名的Java性能工具配對(duì)。
您可以將Java探查器看作是一種反應(yīng)式工具,而Java性能監(jiān)視器則是一種主動(dòng)式工具。您既要確保您的應(yīng)用程序?yàn)槟挠脩粢院芎梅绞竭\(yùn)行,又要避免不必要的停機(jī)時(shí)間。Java性能監(jiān)視工具可以測量應(yīng)用程序的響應(yīng)能力,監(jiān)視sla,甚至可以根據(jù)用戶數(shù)據(jù)計(jì)算許多不同的度量來跟蹤用戶體驗(yàn)。
我們花了一些時(shí)間來尋找一些好的Java性能工具,可以用來幫助防止Java內(nèi)存泄漏,并保持代碼平穩(wěn)運(yùn)行。
以下是我們精選的很好JAVA性能工具:
SolarWinds AppOptics(免費(fèi)試用)提供多種應(yīng)用程序的深度視覺效果和報(bào)告功能。
DataDog Java性能監(jiān)控工具平衡了易用性,同時(shí)優(yōu)先考慮了主動(dòng)特性
VisualVM是一個(gè)簡單的Java探查器,非常適合基本的故障排除。
JProfiler一種付費(fèi)的Java評(píng)測器,可以檢測不同級(jí)別的大量bug
Eclipse內(nèi)存分析器MAT提供了Java堆內(nèi)存的詳細(xì)細(xì)分,以更好地了解內(nèi)存泄漏。
Glowroot一個(gè)開源的性能監(jiān)視器,通過本地瀏覽器顯示數(shù)據(jù)。
SolarWinds公司的AppOptics是一款全服務(wù)的應(yīng)用程序性能監(jiān)視器,為大量不同的應(yīng)用程序構(gòu)建。雖然AppOptics支持許多程序,但它在監(jiān)視和排除Java應(yīng)用程序故障方面做得特別好。
與DataDog類似,AppOptics將強(qiáng)大的功能組合到一個(gè)易于使用的儀表板中,允許您自定義和控制您的監(jiān)視體驗(yàn)??梢詮念^開始創(chuàng)建警報(bào),也可以從軟件附帶的預(yù)配置模板庫中選擇警報(bào)。
雖然儀表板為您提供了應(yīng)用程序及其狀態(tài)的完整概述,但您也可以深入到代碼級(jí)別并將AppOptics用作性能調(diào)諧器。這使得接收實(shí)時(shí)數(shù)據(jù)并立即在同一軟件中進(jìn)行故障排除變得很容易。
開發(fā)人員可以通過監(jiān)視Java堆使用率、調(diào)用數(shù)、錯(cuò)誤率和響應(yīng)時(shí)間等指標(biāo)來監(jiān)視Java應(yīng)用程序是否存在內(nèi)存泄漏或其他許多問題。性能數(shù)據(jù)也可以通過日志、圖表或瀑布跟蹤歷史地查看,這樣可以很容易地縮小時(shí)間范圍并隔離出問題代碼行。
datadog是專門為使監(jiān)視Java應(yīng)用程序成為一個(gè)簡單而直觀的過程而構(gòu)建的。通過交互式儀表板,您可以在服務(wù)、客戶和端點(diǎn)級(jí)別查看Java代碼的狀態(tài)。Datadog通過一個(gè)簡單的軟件即服務(wù)(SaaS)模型提供了這些見解。
一旦您輸入了代碼,DataDog就可以通過自動(dòng)生成的服務(wù)映射識(shí)別Java問題、依賴關(guān)系和機(jī)會(huì)。所有這些數(shù)據(jù)都是從向DataDog報(bào)告信息的簡單代理安裝中提取的。主儀表板將實(shí)時(shí)和歷史性能信息作為可視化和列表項(xiàng)引入,您可以對(duì)其進(jìn)行排序。
總錯(cuò)誤、延遲和請求數(shù)等指標(biāo)可以通過儀表板輕松跟蹤。可以將此視圖更改為網(wǎng)絡(luò)拓?fù)湟晥D,以幫助更好地可視化查詢之間的關(guān)系,以及性能如何影響鏈下游的其他功能。
通過警報(bào)儀表板,您可以根據(jù)正常運(yùn)行時(shí)間、異常情況或您設(shè)置的特定閾值快速設(shè)置通知。很高興看到這個(gè)軟件允許您在設(shè)置警報(bào)模板時(shí)組合觸發(fā)條件。通過盡可能細(xì)化您的警報(bào)條件,它有助于減少警報(bào)疲勞,并保持您的收件箱干凈。警報(bào)可以通過電子郵件發(fā)送,也可以發(fā)送到Slack或Pagerduty等其他工具。
當(dāng)您處理像Java應(yīng)用程序的性能監(jiān)視這樣復(fù)雜的事情時(shí),找到一個(gè)既直觀又強(qiáng)大的工具會(huì)讓您耳目一新。您可以免費(fèi)測試DataDog及其所有功能14天。
VisualVM是一個(gè)Java故障排除工具,它直接連接到JDK來檢測問題,并通過圖形界面引起您的注意。開發(fā)人員可以查看他們的應(yīng)用程序堆轉(zhuǎn)儲(chǔ),分析他們的代碼,并查看他們的Java應(yīng)用程序的許多其他見解。因?yàn)樗苯咏壎ǖ侥腏DK中,所以可以方便地從您正在工作的地方訪問它。
VisualVM相當(dāng)輕量級(jí),并且直接駐留在本地計(jì)算機(jī)上,這使得它非常適合在運(yùn)行中進(jìn)行故障排除,而且不必依賴基于SaaS的產(chǎn)品。雖然還有其他工具可以提供對(duì)Java相關(guān)問題的更深入的見解,但VisualVM是一個(gè)簡單而干凈的工具,它非常適合在故障排除過程的開始使用。
當(dāng)談到Java分析器時(shí),VisualVM是一個(gè)很好的起點(diǎn),但是您可能需要考慮將其與性能監(jiān)視工具或其他更詳細(xì)的探查器配對(duì),以確保找到所有潛在的bug。
您可以在Windows、Linux或macOS操作系統(tǒng)上免費(fèi)下載VisualVM
JProfiler by EJ Technologies是一款Java評(píng)測器,它以易用性和與Java應(yīng)用程序的輕松集成而自豪。在JVM級(jí)別,您可以在執(zhí)行代碼時(shí)查看并快速診斷代碼中的問題。像Java代碼中的內(nèi)存泄漏這樣的問題會(huì)在堆內(nèi)存分析器下快速突出顯示。打開和關(guān)閉的連接可以通過一個(gè)彩色編碼的時(shí)間線可視化,這樣就可以很容易地看到丟失的連接,這些連接保持打開狀態(tài)并利用資源。JProfiler還有一個(gè)內(nèi)置的堆遍歷器,開發(fā)人員可以使用它從多個(gè)角度查看任何一組對(duì)象,以便進(jìn)行更深入的檢查。
默認(rèn)情況下支持JEE,并將JEE組件分組到調(diào)用樹中的組中,這樣可以更容易地對(duì)更高級(jí)別的分析數(shù)據(jù)進(jìn)行排序,下到粒度級(jí)別和其他子系統(tǒng)。
JProfiler與Windows、Linux和macOS兼容,可以使用試用密鑰免費(fèi)測試。
為了獲得堆內(nèi)存的詳細(xì)細(xì)分,Eclipse內(nèi)存分析器被設(shè)計(jì)成突出顯示內(nèi)存收集中的缺陷并監(jiān)視Java堆使用的健康狀況。存儲(chǔ)的任何對(duì)象都將顯示并在堆中可見,Eclipse內(nèi)存分析器將監(jiān)視和報(bào)告內(nèi)存的分配方式以及是否已清除。
儀表板精確地分解堆的大小,以及圖表格式中哪些對(duì)象的大小較大。您可以配置自己的視圖,也可以使用許多預(yù)先配置的視圖按對(duì)象大小、重復(fù)類或頂級(jí)使用者進(jìn)行排序。這些指標(biāo)可以幫助您快速解決堆中的問題,并為優(yōu)化性能設(shè)置更好的策略。
Eclipse內(nèi)存分析器可以免費(fèi)下載,并且與Windows、Linux和macOS系統(tǒng)兼容。
Glowroot是一個(gè)開源的java apm,設(shè)置起來很快,也很容易開始使用。只需將根目錄文件解壓并添加到你的瀏覽器面板上。
如果您需要一個(gè)開銷極低的工具,Glowroot在資源消耗方面處于類的首位。大量的測試表明,Glowroot在其環(huán)境中造成的影響非常小,因此響應(yīng)時(shí)間必須以微秒為單位進(jìn)行記錄。
除了運(yùn)行極其精簡的Glowroot之外,Glowroot還有許多其他特性,可以用來分析和監(jiān)視Java應(yīng)用程序。所有數(shù)據(jù)的實(shí)時(shí)和歷史匯總可以通過MBean支持圖表輕松執(zhí)行實(shí)時(shí)和長期測試。雖然Glowroot并不是功能最豐富的性能監(jiān)視器,但它確實(shí)提供了可配置的警報(bào)功能,從而為長期使用提供了額外的靈活性。
Glowroot可以免費(fèi)下載,如果你想體驗(yàn)一下這個(gè)工具,它還附帶了一個(gè)方便的演示站點(diǎn)。
https://glowroot.org/overhead.html
Java內(nèi)存泄漏可能會(huì)令人沮喪,但是確切地知道它是什么以及如何對(duì)其進(jìn)行故障排除將使處理它們變得更加容易。我們知道Java內(nèi)存泄漏是由于堆內(nèi)存中的對(duì)象未清理而導(dǎo)致的。讓我們回顧一下修復(fù)和防止內(nèi)存泄漏的很好方法。
使用Java編譯器 - 你的工具包是一個(gè)很好的選擇,這些工具將幫助您節(jié)省數(shù)不清的調(diào)試時(shí)間,并有助于突出顯示代碼中本來很難找到的問題。
使用可信的Java性能監(jiān)視器 - Java性能監(jiān)視器不僅可以提醒您代碼中的問題,還可以幫助您在應(yīng)用程序中發(fā)現(xiàn)內(nèi)存泄漏的跡象,以免它影響到您的用戶。
審核你的代碼 - 在實(shí)現(xiàn)新代碼時(shí),定期的審核和測試可以起到很大的作用。安排審核以及清理Java將幫助您的應(yīng)用程序運(yùn)行更快,并使故障排除變得更容易。
關(guān)于Java項(xiàng)目中出現(xiàn)內(nèi)存溢出的原因有哪些就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。