2016-12-17 35 views
0

Javaでは、「通常の」HashSetと比較してLinkedHashSetの消費量はどれくらいですか? LinkedHashSetは特定の操作では少し遅いのですが、メモリ使用量はどうですか?LinkedHashSetと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の場合、少なくともホットスポットで> 32GBのヒープをヒットするまではそうです。 – BeeOnRope

+0

あなたはそれを使用しているはずですので、ほとんどのシナリオではこれが最も現実的な数字になるはずです。 –

+0

ええ、既定ではオンになっているので、ほとんどの人が知っているかどうかにかかわらず、それを使用しています。リンクされたノードのメモリ使用を気にする人は、巨大なヒープを使用しています。 – BeeOnRope

2

HashSetのコアとは別に、LinkedHashSetという名前が示すとおり、ドキュメントの状態が明示的に示されており、リンクされたリストを維持する必要があります。ここでは、メモリ消費量の上限は、ハッシュセットとリンクリストという2つの別個のデータ構造を持っているかのように近似することができます。彼らがどれほど記憶を消費するかは別の質問です。

ただし、使用するメモリのバイト数にハードデータが必要な場合は、いつでも独自のテストを実行できます。テストするのはあまり難しいことではありませんし、しばらくはGoogleを使ってはいけません。インターネット上ですでにいくつかのテスト結果が利用可能であると確信しています。差が小さい理由

@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 KiBので異なります)私は下記提示され妖精安定した結果を出力し、それを私が気づい数回実行した後:

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 

興味深いことに、それはルイスによって与えられた値と一致しません。しかし、1要素あたりのバイト数の差は、ルイが書いたもの(8B)と同じです。誰かが値の不一致を説明できますか?オブジェクトのサイズを間違って測定していますか?

+2

'HashSet'は32バイト/エレメントです。 'LinkedList'は24バイト/エレメント、' LinkedHashSet'は40バイト/エレメントです。彼らはちょうど追加するだけではありません。 –

+0

「CompressedOops」をオンにした場合としない場合の両方で、32ビットと64ビットのJVMの違いがあります。 –

関連する問題