如何在HashMap中插入后在内存中查找大小?

时间:2014-04-13 07:51:26

标签: java hashmap performance-testing

我正在对HashMap插入进行一些性能测试。我正在测试的操作是在插入后插入,读取和在内存中调整大小。

我可以做,插入和阅读测试,但不知道如何找到size in memory after insertion -

我有一个文本文件,其中包含200万个英文单词,其频率为此格式 -

hello 100
world 5000
good 2000
bad 9000
...

现在我逐行读取此文件并将其存储在HashMap中,以便我可以使用以下代码测量插入性能。

Map<String, String> wordTest = new HashMap<String, String>();

try {
    fis = new FileInputStream(FILE_LOCATION);
    reader = new BufferedReader(new InputStreamReader(fis));

    String line = reader.readLine();
    long startTime = System.nanoTime();
    while (line != null) {
    String[] splitString = line.split("\\s+");
    // now put it in HashMap as key value  pair
    wordTest.put(splitString[0].toLowerCase().trim(), splitString[1].trim());

    line = reader.readLine();
    }
    long endTime = System.nanoTime() - startTime;
    System.out.println("Insertion Time: " +TimeUnit.MILLISECONDS.convert(endTime, TimeUnit.NANOSECONDS));
}

现在我还要在上面size in memory after insertion中衡量HashMap

基本上我看了这个链接后感到困惑 - https://github.com/jpountz/tries/wiki/Benchmark。在这个链接中,他们有size in memory after insertion但不确定它是什么意思以及他们如何计算它?有什么方法可以用Java做同样的事情吗?

4 个答案:

答案 0 :(得分:15)

再一次,我想请注意,如果您使用Unsafe挖掘VM的头脑,可以获得Java对象的确切内存占用量测量值。有很多项目使用该技术,其中一个是jol,可在OpenJDK中使用(这意味着它也适用于Oracle JDK)。例如,这是显示ArrayList与LinkedList脚印的runnable sample

Running 64-bit HotSpot VM.
Using compressed references 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]

java.util.ArrayList instance footprint:
 COUNT   AVG   SUM DESCRIPTION
     1  4952  4952 [Ljava.lang.Object;
  1000    16 16000 java.lang.Integer
     1    24    24 java.util.ArrayList
  1002       20976 (total)


java.util.LinkedList instance footprint:
 COUNT   AVG   SUM DESCRIPTION
  1000    16 16000 java.lang.Integer
     1    32    32 java.util.LinkedList
  1000    24 24000 java.util.LinkedList$Node
  2001       40032 (total)

您可以将jol作为依赖项,并将HashMap实例提供给它。

答案 1 :(得分:2)

尽管使用外部工具是一种可行的解决方案,但简单的Java方法是:

long myTotalMemoryBefore = Runtime.getRuntime().totalMemory();

/* Fill the hash Table */

long myTotalMemoryAfter = Runtime.getRuntime().totalMemory();
long myHashMapMemory = myTotalMemoryAfter - myTotalMemoryBefore;

值以字节为单位,除以1024到Kbytes等等......

详细信息:

http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#totalMemory%28%29

在这里:

What are Runtime.getRuntime().totalMemory() and freeMemory()?

答案 2 :(得分:1)

您需要jconsole等工具才能在运行时更好地监控内存。

enter image description here

答案 3 :(得分:-4)

检查您的任务管理器,看看java.exe的大小。在运行程序时查看更改的最佳方法是杀死java.exe,如果运行服务器,也会停止服务器。再次启动您的应用程序,检查java.exe大小是否适合您。使用您的hashmap,而不是触发hashmap操作并再次检查java.exe。如果您只保存少量数据,我不知道您是否会看到更改,如果您尝试在hasmap中保存1GB文件,您将直接看到的内容。要做到这一点,你需要增加你的Java堆。我不知道这个例子是否有效,但here是一个例子,说明如何在运行应用程序时获取内存大小。

How to increase the java heap