hashmap大小_调整HashMap的大小:未来的危险
hashmap大小
最近,我偶然發(fā)現(xiàn)了一個錯誤,該錯誤是由于多個線程對java.util.HashMap的使用不當(dāng)引起的。 該錯誤是泄漏抽象的一個很好的例子。 只有了解數(shù)據(jù)結(jié)構(gòu)的實現(xiàn)級別詳細信息,才能幫助我解決當(dāng)前的問題。 因此,我希望與他人分享我所遇到的問題,以鼓勵一些讀者熟悉基本數(shù)據(jù)結(jié)構(gòu)的實現(xiàn)方式。
在一天中,通常僅需幾分鐘即可完成的某些分析過程已經(jīng)運行了數(shù)小時,因此,我所面對的癥狀每天都變得丑陋。 作為我們技術(shù)的真正信奉者,我們通過自己的監(jiān)控軟件及時得到通知,并開始調(diào)查原因。
我還從處理線程中獲得了幾個線程轉(zhuǎn)儲。 他們指出,該代碼只是在堆轉(zhuǎn)儲中發(fā)現(xiàn)的哈希圖中處理條目,看似處于未終止的循環(huán)中。 因此,似乎正在分析的數(shù)據(jù)以某種方式損壞了,其中包含循環(huán)引用。
令我驚訝的是,確實如此。 分析的堆內(nèi)容中的HashMap條目相互引用。 在設(shè)計堆分析算法時,我們從來沒有想到這是可能的。 顯然我們錯了。
由于已知HashMap實現(xiàn)不是線程安全的,因此我現(xiàn)在懷疑它與HashMap使用的并發(fā)性問題有關(guān)。 實際上,在java.util.HashMap的設(shè)計中隱藏著一個問題。 如您所知, HashMap由存儲區(qū)數(shù)組組成,每個存儲區(qū)都引用一個鏈接的條目列表。 條目依次引用列表中的下一個條目,直到最后一個條目引用null:
我們的分析儀遇到的問題是,兩個條目相互引用形成一個封閉的循環(huán)。
在Google的幫助下,我發(fā)現(xiàn)了最終如何創(chuàng)建這樣的循環(huán)引用是多線程環(huán)境中的一個問題。 再次提醒您, HashMap在運行時會根據(jù)映射中的條目數(shù)動態(tài)調(diào)整大小。 默認情況下, HashMaps使用75%的負載率。 這意味著只要地圖中的條目數(shù)超過可用容量的75%,地圖大小就會增加,以避免在地圖元素條目上發(fā)生太多沖突。
所以我在這里。 顯然,有多個線程試圖同時調(diào)整地圖的大小,從而在某些存儲桶中創(chuàng)建了一個循環(huán)。 罪魁禍?zhǔn)鬃罱K隱藏在Java HashMap源代碼的以下幾行中:
void transfer(Entry[] newTable, boolean rehash) {... skipped for brevity ...Entry next = e.next;if (rehash) {e.hash = null == e.key ? 0 : hash(e.key);}... skipped for brevity ... }現(xiàn)在,我們的分析端點解決方案非常簡單。 我們只需要保留關(guān)于已處理條目的分類帳,而無需對所有條目進行兩次處理即可。
我確實相信這可以作為失敗抽象的一個很好的例子。 Java中的HashMaps構(gòu)建良好,即使您不了解實現(xiàn)細節(jié),也可以很好地為您服務(wù)。 直到他們不這樣做。 在這種情況下,對數(shù)據(jù)結(jié)構(gòu)實現(xiàn)細節(jié)的深入了解將為您帶來一切不同。
翻譯自: https://www.javacodegeeks.com/2016/08/resizing-hashmap-dangers-ahead.html
hashmap大小
總結(jié)
以上是生活随笔為你收集整理的hashmap大小_调整HashMap的大小:未来的危险的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓竖屏锁定哪里设置(安卓竖屏)
- 下一篇: 杨玉环安禄山是什么关系(杨玉环和安禄山之