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