java 对象锁定_少锁定Java对象池
java 對象鎖定
自從我寫任何東西以來已經(jīng)有一段時間了,我一直在忙于我的新工作,其中涉及在性能調(diào)優(yōu)方面做一些有趣的工作。 挑戰(zhàn)之一是減少應用程序關鍵部分的對象創(chuàng)建。
盡管Java隨著時間的推移已改進了GC算法,但垃圾回收打ic一直是Java的主要難題。 Azul是開發(fā)無暫停GC的市場領導者,但Azul JVM并非免費!
創(chuàng)建過多的臨時/垃圾對象并不能很好地工作,因為它為GC創(chuàng)建了工作,并且將對延遲產(chǎn)生負面影響。 過多的垃圾也不能在多核系統(tǒng)上正常工作,因為它會導致緩存污染。
那么我們應該如何解決呢?
垃圾少編碼
僅當您知道需要多少個對象并預先分配它們時,這才有可能,但是實際上很難找到。 但是即使您成功做到了,也必須擔心另一個問題
- 您可能沒有足夠的內(nèi)存來容納所需的所有對象
- 您還必須處理并發(fā)
那么上述問題的解決方案是什么
有一種對象池設計模式可以解決以上兩個問題。 它使您可以指定池中所需的許多對象,并處理并發(fā)請求以服務所請求的對象。
對象池一直是許多具有低延遲要求的應用程序的基礎。 Flyweight設計模式是對象池的一種風格。
上面的兩種模式都將幫助我們避免創(chuàng)建對象。 太好了,因此現(xiàn)在減少了GC工作,并且理論上我們的應用程序性能應該得到改善。 實際上,不會那樣做,因為對象池/ Flyweight必須處理并發(fā),并且由于并發(fā)問題而失去了避免對象創(chuàng)建而獲得的任何優(yōu)勢。
處理并發(fā)的最常見方法是什么
對象池是一個典型的生產(chǎn)者/消費者問題,可以使用以下技術來解決:
同步:這是在JDK 1.5之前處理并發(fā)的唯一方法。 Apache編寫了一個基于同步的出色的對象池 API
鎖: Java在JDK 1.5之后增加了對并發(fā)編程的出色支持。 已經(jīng)有一些使用鎖來開發(fā)對象池的工作,例如, furious-objectpool
無鎖:我找不到使用完全無鎖技術構建的任何實現(xiàn),但是furious-objectpool使用ArrayBlocking隊列和ConcurrentLinked隊列的混合
衡量績效
在此測試中,我創(chuàng)建了一個包含100萬個對象的池,并且這些對象可以通過不同的池實現(xiàn)進行訪問,這些對象將從池中取出并返回到池中。
該測試首先從1個線程開始,然后增加線程數(shù)以衡量不同池在爭用情況下的執(zhí)行情況
- X軸–螺紋數(shù)
- Y軸–以毫秒為單位的時間–越短的時間越好
該測試包括來自Apache的池,Furious池和基于ArrayBlocking的池
Apache的性能最差,并且隨著線程數(shù)量的增加,性能會進一步下降。 原因是Apache池基于大量使用“同步”
其他兩個(基于Furious和ArrayBlocking的池)的性能更好,但是隨著爭用的增加,它們兩者的速度也會降低。
當12個線程試圖訪問該池時,基于ArrayBlocking隊列的池對于100萬個項目大約需要1000毫秒。 內(nèi)部使用Arrayblocking隊列的憤怒池大約需要1975 ms。
我必須進行更詳細的調(diào)查,以找出為什么Furious花費雙倍的時間,因為它也是基于ArrayBlocking隊列的。
數(shù)組阻塞隊列的性能不錯,但這是一種基于鎖定的方法。 如果可以實現(xiàn)無鎖池,我們將獲得哪種類型的性能?
鎖免費游泳池
實現(xiàn)無鎖池不是不可能的,但是有點困難,因為您必須處理多個生產(chǎn)者和消費者。
我將實現(xiàn)一個混合池,該池將在生產(chǎn)者端使用鎖定,而在消費者端使用非阻塞技術。
讓我們看一些數(shù)字
我使用新的實現(xiàn)(FastPool)進行了相同的測試,它比ArayBlocking隊列快了30%。
30%的改善還不錯,它絕對可以幫助我們實現(xiàn)延遲目標。
是什么讓快速池快速!
我使用了兩種技術來使其快速運行
- 生產(chǎn)者是基于鎖的–使用鎖來管理多個生產(chǎn)者,這與“數(shù)組阻止”隊列相同,因此沒什么大不了的。
- 立即發(fā)布已發(fā)布項目–在使用便宜的內(nèi)存屏障釋放鎖之前,它會發(fā)布元素。 這會有所收獲
- 消費者不受阻礙–使用CAS來實現(xiàn)這一目標,消費者永遠不會因生產(chǎn)者而受到阻礙。 數(shù)組阻止隊列阻止使用者,因為它對生產(chǎn)者和使用者使用相同的鎖
- 線程局部以保持值的局部性–線程局部用于獲取最后使用的值,這在很大程度上減少了爭用。
如果您有興趣查看代碼,則可以使用@ FastObjectPool.java
翻譯自: https://www.javacodegeeks.com/2013/07/lock-less-java-object-pool.html
java 對象鎖定
總結
以上是生活随笔為你收集整理的java 对象锁定_少锁定Java对象池的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 死亡骑士天赋冰霜加点(魔兽世界冰霜死亡骑
- 下一篇: java 8 lambda_Java 8