Reputation: 19612
I am working on some performance test on HashMap insertion. Operations on which I am testing are insert, read and size in memory after insertion.
I am able to do, insert and read test but not sure how do I find out size in memory after insertion
-
I have a text file which contains 2 million english words with their frequencies in this format -
hello 100
world 5000
good 2000
bad 9000
...
Now I am reading this file line by line and storing it in HashMap
so I am able to measure the insertion performance with the below code.
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));
}
Now I would also like to measure size in memory after insertion
in my above HashMap
.
Basically I am confuse after taking a look from this link - https://github.com/jpountz/tries/wiki/Benchmark. In this link they have size in memory after insertion
but not sure what does it mean and how they have calculated it? Is there any way I can do the same thing in Java?
Upvotes: 2
Views: 2819
Reputation: 5414
you need a tool such as jconsole to beter monitor the memory at runtime.
Upvotes: 1
Reputation: 2200
Although using an external tool is a viable solution, the easy Java way is:
long myTotalMemoryBefore = Runtime.getRuntime().totalMemory();
/* Fill the hash Table */
long myTotalMemoryAfter = Runtime.getRuntime().totalMemory();
long myHashMapMemory = myTotalMemoryAfter - myTotalMemoryBefore;
The values are in bytes, do divide by 1024 to Kbytes,etc...
Details here:
http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#totalMemory%28%29
and here:
What are Runtime.getRuntime().totalMemory() and freeMemory()?
Upvotes: 2
Reputation: 18847
Once again, I wish to note it is possible to get the exact memory footprint measurement for Java object, if you tap into VM's mind with Unsafe. There are plenty of projects that use that technique, and one of them is jol, available in OpenJDK (which means it works with Oracle JDKs as well). For example, this is the runnable sample showing the ArrayList vs LinkedList footprints:
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)
You can pull jol as the dependency, and feed your HashMap instance to it.
Upvotes: 15
Reputation: 159
Check your task manager and have a look how large java.exe is. Best way to see changes while running your program is you kill the java.exe, that will also stop your server if you run one. Than start your application again, check java.exe size befor your do sth. with your hashmap, than trigger the hashmap action and check java.exe again. I dont know if you will see changes if you only save a small amount of data, what you will see directly is if you try to save 1GB file in your hasmap. To do this you need to increase your java heap befor. I dont know if this example is working but here is an example how you could get your memory size while running your application.
Upvotes: -4