2016-12-17 77 views
0

在Java中,與「常規」HashSet相比,Java中有多少內存(字節)是LinkedHashSet? 我知道LinkedHashSet對於某些操作稍慢,但內存使用情況如何?LinkedHashSet vs HashSet內存消耗

+0

沒有看到那個笨蛋@Bruno_Ferreira – pvg

+0

可能是幾個指針和列表標題的代價。你是否在[GrepCode](http://grepcode.com)上檢查實現源? –

回答

3

https://github.com/DimitrisAndreou/memory-measurer/blob/master/ElementCostInDataStructures.txt

HashSet一個是〜32個字節/元件;一個LinkedHashSet是〜40個字節/元素。

+0

對於可能假設「CompressedOops」處於活動狀態的64位JDK,應該是這種情況,直到您至少在Hotspot上點擊> 32GB堆爲止。 – BeeOnRope

+0

你確定_應該使用它,所以是的,這應該是大多數情況下最現實的數字。 –

+0

是的,這是默認的,所以大多數人都在使用它,不管他們是否知道。它可能會讓那些關心內存使用鏈接節點的人使用一個巨大的堆。 – BeeOnRope

2

顧名思義,文檔狀態明確,LinkedHashSet,除了核心HashSet,需要維護一個鏈表。我認爲這裏假設內存消耗的上限可以近似,就好像你只有兩個獨立的數據結構:一個散列集和一個鏈表。他們消耗多少內存,是一個單獨的問題。但是,如果您需要關於使用的內存字節數的硬數據,您可以隨時自行執行一些測試。測試或谷歌一段時間不應該太難 - 我確定互聯網上已經有一些測試結果可用。

@edit,路易斯的回答後

這似乎有趣,我爲什麼差別較小。這裏有一個簡單的基準我寫道:

package com.company; 

import com.javamex.classmexer.MemoryUtil; 

import java.util.HashSet; 
import java.util.LinkedHashSet; 
import java.util.Random; 

public class Main 
{ 
    public static void main(String[] args) 
    { 
     // Creating data structures under test ------- 
     HashSet<Integer> hashSet = new HashSet<>(); 

     Random random = new Random(); 
     for (int i=0; i<1000000; i++) 
     { 
      hashSet.add(random.nextInt()); 
     } 

     LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>(hashSet); 

     // Measuring memory usage -------------------- 
     long sizeOfHashSet = MemoryUtil.deepMemoryUsageOf(hashSet); 
     long sizeOfLinkedHashSet = MemoryUtil.deepMemoryUsageOf(linkedHashSet); 
     System.out.println("Size of HashSet:\n" + sizeOfHashSet + " B"); 
     System.out.println("Size of LinkedHashSet:\n" + sizeOfLinkedHashSet + " B"); 
     System.out.println("LinkedHashSet is bigger from HashSet by " + (sizeOfLinkedHashSet*100/sizeOfHashSet - 100) + "%"); 

     System.out.println("\n"); 

     long numberOfElements = hashSet.size(); 
     System.out.println("Number of elements in the test HashSet: " + numberOfElements); 

     System.out.println("Average size of a single element in HashSet: " + sizeOfHashSet/numberOfElements + " B"); 
     System.out.println("Average size of a single element in LinkedHashSet: " + sizeOfLinkedHashSet/numberOfElements + " B"); 
    } 
} 

它運行了好幾次,我注意到它打印出童話穩定的結果(目標大小由+/- 2昆明植物研究所不同)我下面要介紹後:

Size of HashSet: 
56347616 B 
Size of LinkedHashSet: 
64348040 B 
LinkedHashSet is bigger from HashSet by 14% 

Number of elements in the test HashSet: 999876 
Average size of a single element in HashSet: 56 B 
Average size of a single element in LinkedHashSet: 64 B 

有趣的是,它不符合路易斯給出的價值。但是,每個元素的字節差異與Louis寫的相同(8 B)。有人可以解釋價值觀的差異嗎?我是否以錯誤的方式測量物體的大小?

+2

'HashSet'是32字節/元素; 'LinkedList'是24個字節/元素,'LinkedHashSet'是40個字節/元素。他們不完全只是添加。 –

+0

在運行32位與64位JVM時可能存在差異,有或沒有'CompressedOops',等等。 –