2013-04-09 22 views
5

Basit bir B-Tree uyguladınız; Şimdi aşağıdaki yöntemi kullanarak ona bellek kullanımını tahmin etmek istedik (JVM sadece 32bit için geçerlidir):Java'da bir B Ağacının bellek kullanımını hesaplama

class BTreeEntry { 

    int entrySize; 
    long keys[]; 
    int values[]; 
    BTreeEntry children[]; 
    boolean isLeaf; 
    ... 
    /** @return used bytes */ 
    long capacity() { 
     long cap = keys.length * (8 + 4) + 3 * 12 + 4 + 1; 
     if (!isLeaf) { 
      cap += children.length * 4; 
      for (int i = 0; i < children.length; i++) { 
       if (children[i] != null) 
        cap += children[i].capacity(); 
      } 
     } 
     return cap; 
    } 
} 
/** @return memory usage in MB */ 
public int memoryUsage() { 
    return Math.round(rootEntry.capacity()/(1 << 20)); 
} 

Ama mesela denedim 7mio girişleri ve memoryUsage yöntemi için -Xmx ayarından çok daha yüksek değerler bildirilir! Örneğin. 1040 (MB) diyor ve ben -Xmx300'ü ayarlıyorum! JVM bir şekilde bellek düzenini optimize edebilir mi, örn. boş diziler için ya da benim hatam olabilir?

Güncelleme1: Tamam, isLeaf boolean'ı tanıtmak bellek kullanımını çok fazla azaltır, ancak yine de neden Xmx'ten daha yüksek değerler aldığımı belirsiz. (Yine de, tüm müteahhitler için isLeaf == false kullanarak bunu deneyebilirsiniz)

Update2: Hmmh, bir şey çok yanlış. Yaprak başına girişleri arttırırken, bellek kullanımının azaldığı varsayılır (her ikisi için de kompakt yapılırken), çünkü daha büyük diziler için referansların daha az yükü vardır (ve btree daha küçük bir boyuta sahiptir). Ancak, memoryUsage yöntemi, yaprak başına 100 giriş yerine 500 kullanırsam, artan bir değer bildirir.

+0

3 * 12 uzun kapasitenin kaynağı nedir? – Erik

+0

Uzun ve int'nin bellek tüketim değerleri için kaynağınız nedir? – PeterMmm

+0

@Erik 3 * 12 -> 3 diziye referanslar. – Karussell

cevap

0

Ohh sh ... temiz hava bu sorunu çözmüş biraz;)

bir giriş o parçalı olacak doludur. Eski çocuk işaretçileri hâlâ açık olduğundan, is burada

// left child: just copy pointer and decrease size to index 
BTreeEntry newLeftChild = this; 
newLeftChild.entrySize = splitIndex; 

sorunu: (Ben belleğin israfını önlemek istediği yerde) benim orijinal bölünmüş yöntemine checkSplitEntry ben büyük bir hafıza kaybı hata yaptı. Ve böylece, memoryUsage yöntemimde bazı çocukları iki kez sayıyorum (özellikle de kompakt olmadığımda!). Yani, bu hile olmadan tüm iyi olmalı ve B-Ağacı çöp toplayıcı işlerini yapabilir gibi daha da fazla bellek verimli olacak!