2016-02-27 41 views
0

我在多個使用byte []而不是string的地方讀取它會節省您的內存。我想用jol進行測試。使用字符串vs byte []作爲值,地圖中的內存使用情況

這裏我的測試:

public static void main (String[] args) throws java.lang.Exception{ 
    System.out.println(VMSupport.vmDetails()); 
    String StrByte = GraphLayout.parseInstance(sizeOfStrByteMap(100000)).toFootprint(); 
    String ByteByte = GraphLayout.parseInstance(sizeOfByteByteMap(100000)).toFootprint(); 
    String StrStr  = GraphLayout.parseInstance(sizeOfStrStrMap(100000)).toFootprint(); 
    System.out.println(StrByte); 
    System.out.println(ByteByte); 
    System.out.println(StrStr); 
} 

public static HashMap<String, String> sizeOfStrStrMap(int size) { 
    String value = "this is the sample value"; 

    HashMap<String, String> map = new HashMap<>(); 
    for (int i = 0; i < size; i++) { 
     map.putIfAbsent(Integer.toString(i), value); 
    } 
    return map; 
} 

public static HashMap<String, byte[]> sizeOfStrByteMap(int size) { 
    byte[] value = "this is the sample value".getBytes(); 

    HashMap<String, byte[]> map = new HashMap<>(); 
    for (int i = 0; i < size; i++) { 
     map.putIfAbsent(Integer.toString(i), value); 
    } 
    return map; 
} 

public static HashMap<byte[], byte[]> sizeOfByteByteMap(int size) { 
    byte[] value = "this is the sample value".getBytes(); 

    HashMap<byte[], byte[]> map = new HashMap<>(); 
    for (int i = 0; i < size; i++) { 
     map.putIfAbsent(Integer.toString(i).getBytes(), value); 
    } 
    return map; 
} 

這裏是我的結果:

Running 64-bit HotSpot VM. 
Using compressed oop with 3-bit shift. 
Using compressed klass with 3-bit shift. 
Objects are 8 bytes aligned. 
Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] 
Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] 

// StrByteMap 
[email protected] footprint: 
    COUNT  AVG  SUM DESCRIPTION 
     1  184  184 [B 
    100000  31 3120000 [C 
     1 1048592 1048592 [Ljava.util.HashMap$Node; 
    100000  24 2400000 java.lang.String 
     1  48  48 java.util.HashMap 
    100000  32 3200000 java.util.HashMap$Node 
    300003    9768824 (total) 

// ByteByteMap 
[email protected] footprint: 
    COUNT  AVG  SUM DESCRIPTION 
    100001  24 2400184 [B 
     1 1048592 1048592 [Ljava.util.HashMap$Node; 
     1  48  48 java.util.HashMap 
    100000  32 3200000 java.util.HashMap$Node 
    200003    6648824 (total) 


// StrStrMap 
[email protected] footprint: 
    COUNT  AVG  SUM DESCRIPTION 
    100001  31 3120344 [C 
     1 1048592 1048592 [Ljava.util.HashMap$Node; 
    100001  24 2400024 java.lang.String 
     1  48  48 java.util.HashMap 
    100000  32 3200000 java.util.HashMap$Node 
    300004    9769008 (total) 

正如你所看到的,StrByteMap和StrStrMap之間的內存使用率幾乎是相同的。我在這裏測試錯了嗎?

UPDATE: 請參考下面@Amod潘迪的question,我也想知道爲什麼。

+0

鑑於數組字節和字符串是不可互換的東西,這個問題是沒有意義的。 – Raedwald

回答

3

對於Map測試,您將放入相同的值引用,因此它不會佔用太多空間。以同樣的方式,你有不同的關鍵你需要使價值不同或如你所見,值類型的選擇沒有太大的區別。

+1

另外應該注意的是'getBytes()'取決於系統默認的語言環境。如果它是UTF-16,結果會有所不同。 –

+0

@TagirValeev OP似乎使用ASCII,但對於某些字符,不同的編碼也會有不同的長度,給出不同的大小+1 –

1

我覺得很奇怪。

// StrByteMap 
[email protected] footprint: 
    COUNT  AVG  SUM DESCRIPTION 
     1  184  184 [B 
    100000  31 3120000 [C 

有一個byte arrary實例和100000個char數組實例。這是100001的情況下的strstr

// StrStrMap 
[email protected] footprint: 
    COUNT  AVG  SUM DESCRIPTION 
    100001  31 3120344 [C 

所以,即使你已經存儲字節數組的內存佔用字符數組的字符數組!

另一點是ByteByte字節數組對象的平均大小是24,它小於184(StrByteMap)的字節數組大小,並且在所有三種情況下不應該總計數相同。

+0

我不知道。我也有興趣知道爲什麼。也許有人可以解釋? – LuckyGuess