BigMemroy系列文章--11. BigMemory中的SizeOf问题
轉(zhuǎn)載請注明出處哈:http://carlosfu.iteye.com/blog/2237511
?感謝博主:hot66hot.iteye.com/
?一:BigMemory如何使用DirectMemory內(nèi)存
?
? ?以下是bigMemory啟動時打印的DirectMemory分區(qū)概述:
Maximum Size (specified) : 32MBMinimum Chunk Size : 8MB
Maximum Chunk Size : 32MB
Concurrency : 16
Initial Segment Table Size : 64 slots
Segment Data Page Size : 64KB
?
根據(jù)日志,可以猜測出BigMemory預(yù)先將數(shù)據(jù)空間劃分為一系列Chunk,目的為了防止內(nèi)存碎片化,與Memcache內(nèi)存分配策略很像.
借用下memcache 的chunk空間分配過程圖,可以更好的理解.
?
有個問題:bigMemory必須知道存儲的對象所占用的空間,才能選擇合適的chunk存放對象.
?
二:BigMemory計算對象所占空間
?
EHCache計算一個實例占用的內(nèi)存大小。
基本思路:遍歷實例數(shù)上的所有節(jié)點,對每個節(jié)點計算其占用的內(nèi)存大小。
使用反射的方式計算一個實例占用的內(nèi)存大小。
反射計算一個實例(instance)占用內(nèi)存大小(size)過程如下:?
? a. 如果instance為null,size為0,直接返回。?
? b. 如果instance是數(shù)組類型,size為數(shù)組頭部大小+每個數(shù)組元素占用大小* 數(shù)組長度+填充到對象對齊最小單位。?
? c. 如果instance是普通實例,size初始值為對象頭部大小,然后找到對象對應(yīng)類的所有繼承類,從最頂層類開始遍歷所有類,對每個類,紀(jì)錄長整型和雙精度型、整型和浮點型、短整型和字符型、布爾型和字節(jié)型以及引用類型的非靜態(tài)字段的個數(shù)。在所有類計算完成后,按類對齊規(guī)則對齊等
參考資料:http://www.importnew.com/1305.html
?
EHCache中的SizeOf類中采用deepSize計算,它的步驟是:使用ObjectGraphWalker遍歷一個實例的所有對象引用,在遍歷中通過使用傳入的SizeOfFilter過濾掉那些不需要的字段,然后調(diào)用傳入的Visitor對每個需要計算的實例做計算。?
ObjectGraphWalker的實現(xiàn)算法使用了Stack,也可以使用Queue,這個影響遍歷的順序,深度優(yōu)先還是廣度優(yōu)先的區(qū)別。它抽象了SizeOfFilter接口,可以用于過濾掉一些不想用于計算內(nèi)存大小的字段,如Element中的key字段。SizeOfFilter提供了對類和字段的過濾:
?
? ?SizeOfFilter的實現(xiàn)類可以用于過濾過濾掉@IgnoreSizeOf注解的字段和類,以及通過net.sf.ehcache.sizeof.filter系統(tǒng)變量定義的文件,讀取其中的每一行為包名或字段名作為過濾條件。最后,為了性能考慮,它對一些計算結(jié)果做了緩存。?
結(jié)論: Bigmemory的主要開銷:序列化+sizeOf計算
?
三:sizeOf引擎優(yōu)化與測試:
?
1:對sizeOf引擎友好的對象:盡量使用不深/不廣的對象:深(繼承樹) 廣( bigPojo,ArrayList,HashMap等)
2:這邊使用了大量的ArrayList和HashMap 等對象.日志給出bigMemory警告如下,
2014-04-09 17:30:54,376 [DubboServerHandler-10.10.34.12:20880-thread-248] WARN net.sf.ehcache.pool.impl.DefaultSizeOfEngine (DefaultSizeOfEngine.java:194) - The configured limit of 2,000 object references was reached while attempting to calculate the size of the object graph. This can be avoided by adding stop points with @IgnoreSizeOf annotations. Since the CacheManger or Cache <sizeOfPolicy> elements maxDepthExceededBehavior is set to "abort", the sizing operation has stopped and the reported cache size is not accurate. If performance degradation is NOT an issue at the configured limit, raise the limit value using the CacheManager or Cache <sizeOfPolicy> elements maxDepth attribute. For more information, see the Ehcache configuration documentation.?
為了減少sizeOf計算開銷,加入配置:計算超過2000次后終止,但這樣會造成chunk分配混亂.
?
<sizeOfPolicy maxDepth="2000" maxDepthExceededBehavior="abort"/>?
3:采用protostuff預(yù)前序列化的方式,bigMemory只存protostuff序列化后的byte數(shù)組
如下圖:
?
?
?4:測試用例: 測試采用單線程壓測100W次,directMemory空間為100MB.,對象實際值完全相同.
?
四、結(jié)論:?
1. 采用預(yù)序列化(protostuff)之后set性能有3倍的提高,get性能提高50%以上。
2. 隨著對象復(fù)雜度增加,相同空間預(yù)序列化(protostuff)方式占用空間更少,如HashMap的測試用例.
3. 但是如果對象是簡單的pojo,則原生的bigMemory占用空間更有優(yōu)勢.
4. 根據(jù)自身系統(tǒng)的對象類型做處理.
總結(jié)
以上是生活随笔為你收集整理的BigMemroy系列文章--11. BigMemory中的SizeOf问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BZOJ 3224: Tyvj 1728
- 下一篇: Entity Framework Cod