您的JVM是否泄漏文件描述符-像我的一样?
前言:此處描述的兩個問題是在一年前發(fā)現(xiàn)并修復(fù)的。 本文僅用作歷史證明,也是有關(guān)解決Java中文件描述符泄漏的初學(xué)者指南。
在Ultra ESB中,我們使用內(nèi)存RAM磁盤文件緩存來進(jìn)行快速且無垃圾的有效負(fù)載處理。 一段時間以前,我們在共享的SaaS AS2網(wǎng)關(guān)上遇到了一個問題,該緩存隨著時間的推移泄漏了文件描述符。 最終,在擊中系統(tǒng)ulimit時,導(dǎo)致too many open files錯誤too many open files 。
有彈性的城堡軍團(tuán):流支持的MIME部分中的剩余部分?
我們發(fā)現(xiàn)罪魁禍?zhǔn)资荁ouncy Castle ,這是著名的安全服務(wù)提供商,自Ultra ESB Legacy時代起就一直是我們的摯愛。
通過一些簡單的工具,我們發(fā)現(xiàn)BC習(xí)慣了對MIME部分調(diào)用getContent()以確定它們的類型(例如, instanceof檢查)。 沒錯,這本身并不是犯罪。 但是我們的大多數(shù)MIME部分都是文件支持的 ,另一端帶有文件緩存文件-這意味著每個getContent()都會為該文件打開一個新流。 因此,現(xiàn)在有指向我們的文件緩存的雜散流(以及文件描述符)。
這些已經(jīng)足夠了,我們將用盡分配給Ultra ESB(Java)進(jìn)程的文件描述符配額。
讓他們變得懶惰!
我們不想弄亂BC代碼庫。 因此,我們找到了一個簡單的解決方案:使用“惰性”流創(chuàng)建所有文件支持的MIME部分。 我們(以前)同事Rajind寫了LazyFileInputStream -靈感LazyInputStream從jboss-vfs -打開只有當(dāng)實際文件read嘗試。
BC很高興,文件緩存也很高興。 但是我們是最快樂的
Hibernate JPA:晚飯后清理,也就是關(guān)閉消耗的流
我們發(fā)現(xiàn)的另一個錯誤是某些數(shù)據(jù)庫操作留下了未關(guān)閉的文件句柄。 顯然,只有當(dāng)我們將流支持的Blob饋送到Hibernate時,流才通常來自文件緩存項。
經(jīng)過一番挖掘之后,我們提出了一個理論,即Hibernate不會關(guān)閉這些Blob條目的基礎(chǔ)流。 (這是有道理的,因為java.sql.Blob接口沒有公開Hibernate可以用來操作基礎(chǔ)數(shù)據(jù)源的任何方法。)但是,這是一個問題,因為丟棄的流(以及關(guān)聯(lián)的文件句柄)不會得到發(fā)布直到下一個GC。
對于一個短期應(yīng)用程序來說,這本來可以,但是像我們這樣長期運(yùn)行的應(yīng)用程序很容易用完文件描述符。 例如突然而持續(xù)的峰值。
讓他們自動關(guān)閉!
我們不想失去流媒體的好處,但是我們也無法控制流媒體。 您可能會說我們應(yīng)該將流放在可自動關(guān)閉的結(jié)構(gòu)中(例如try-with-resources )。 不錯的嘗試; 但是可悲的是,Hibernate在我們的執(zhí)行范圍之外(特別是在@Transactional流中)讀取它們。 一旦我們開始在代碼范圍內(nèi)關(guān)閉流,我們的數(shù)據(jù)庫操作就開始慘敗-尖叫“流已關(guān)閉!”。
他們說, 在羅馬時,就像羅馬人一樣 。
因此,我們決定不打擾Hibernate,而是決定自己處理流。
Rajind(是的,還是他)再次入侵了SelfClosingInputStream包裝器 。 這將跟蹤從底層流讀取的數(shù)據(jù)量,并在讀取最后一個字節(jié)后立即將其關(guān)閉。
(我們確實考慮過使用現(xiàn)有選項,例如來自Apache commons-io AutoCloseInputStream ;但是發(fā)生了,我們到處都需要一些自定義設(shè)置,例如詳細(xì)的跟蹤日志記錄。)
底線
當(dāng)涉及到Java中的資源管理時,很容易過度關(guān)注內(nèi)存和CPU(處理),而忽略其余部分。 但是虛擬資源(例如臨時端口和每個進(jìn)程的文件描述符 )可能同樣重要,甚至更多。
尤其是在長時間運(yùn)行的流程(例如我們的AS2 Gateway SaaS應(yīng)用程序)上,它們實際上可以成為沉默的殺手。
您可以通過兩種主要方式檢測這種“泄漏”:
- “單周期”資源分析 :運(yùn)行一個完整的處理周期,比較前后的資源使用情況
- 長期監(jiān)控 :持續(xù)記錄和分析資源指標(biāo)以識別趨勢和異常
在任何情況下,修復(fù)泄漏都不是一件容易的事。 一旦您清楚地了解要處理的內(nèi)容。
祝您好運(yùn),尋找您的資源消耗d(a)守護(hù)程序!
翻譯自: https://www.javacodegeeks.com/2019/10/is-your-jvm-leaking-file-descriptors-like-mine.html
總結(jié)
以上是生活随笔為你收集整理的您的JVM是否泄漏文件描述符-像我的一样?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑版nba2k13隐藏代码(nba2k
- 下一篇: 中国最美的十大自然景观(全国旅游必去十大