下面是一個簡單的程序,剛剛消耗RAM:
import java.util.*;
/**
RamInit (c) GPLv3
@author Stefan Wagner
@date Do 22. Mär 08:40:40 CET 2012
*/
public class RamInit
{
private java.lang.Object consumer;
public RamInit (char type, int size)
{
switch (type)
{
case 'a': Integer [] ai = new Integer [size];
for (int i = 0; i < size; ++i)
ai[i] = i;
consumer = ai;
break;
case 'l': List<Integer> li = new ArrayList<Integer>();
for (int i = 0; i < size; ++i)
li.add (i);
consumer = li;
break;
case 'h': HashMap <Integer, Integer> hm = new HashMap <Integer, Integer>();
for (int i = 0; i < size; ++i)
hm.put (i, size - i);
consumer = hm;
break;
case 'L': LinkedList <Integer> ll = new LinkedList <Integer>();
for (int i = 0; i < size; ++i)
ll.add (i);
consumer = ll;
break;
default: System.err.println ("invalid: " + type);
}
}
public static void main (String args[])
{
char type = 'a';
int size = 1000000; // 1M
if (args.length == 2)
{
type = args[0].charAt (0);
size = Integer.parseInt (args[1]);
}
try {
new RamInit (type, size);
}
catch (OutOfMemoryError oome)
{
System.exit (1);
}
}
}
這裏是一個非常簡單的腳本來測試它:
#!/bin/bash
iterProg() {
ram=$1
maxram=$2
typ=$3
size=$4
# echo java -Xmx${ram}M RamInit $typ $((size*1000*1000))
echo -n "."
java -Xmx${ram}M RamInit $typ $((size*1000*1000)) && echo -en "\n"$typ $size ${ram}M || {
if (($ram==$maxram))
then
# echo "fail"
return
else
iterProg $((ram+1)) $maxram $typ $size
fi
}
}
# try from 16 MB to 256
for typ in {a,l,h,L}; do
for size in {1,2,4}; do
iterProg $((size*17+1)) 256 $typ $size
done
done
這是一種原始的迭代器,並應及時更換通過更復雜的事情 - 例如,如果您需要37MB來爲RamInit調用Collection a和1M元素,那麼您應該開始使用2M元素以上的元素。
而且您應該選擇二進制搜索的步驟,例如,如果20M太少,請選擇128,然後選擇(20 + 128)/ 2,然後選擇平均值,具體取決於成功或失敗的下限或上限。
由於HashMap每個元素存儲2個Ints,因此它可以以大約兩倍的List/Array/Vector大小開始。但是 - 時間過得就像一個箭頭,一邊寫,結果完成:
bash iterRamFind.sh
..
a 1 19M.....
a 2 39M...............
a 4 83M..
l 1 19M.......
l 2 41M.......................
l 4 91M..............................................
h 1 63M.............................................................................................
h 2 127M...........................................................................................................................................................................................
h 4 255M......................
L 1 39M.................................................
L 2 83M...............................................................................................
L 4 163
值17從第一個實驗解釋本身。我們可以看到,尺寸幾乎呈線性增長。
修改代碼來檢查的影響,就要使用多頭,是你 - 我想你會的2
我知道我已經回答了那些東西了好幾次,但是我甚至找不到我自己的帖子。下面是熱點的非常短的,不完整的版本:每個對象都有2個字開銷並且是8字節對齊的。數組的大小有額外的4字節。參考大小取決於JVM位數,但64位系統上的堆<32gb存在壓縮oops。 – Voo 2012-03-22 02:03:03
我不知道visualvm是否可以爲你做...這是一個內存分析器,但我從來沒有使用它。 – 2012-03-22 02:17:51
我還沒有設法找到你的答案,要麼= D如果你可以找到你的一箇舊的答案,涵蓋這將是可怕的。 – 2012-03-22 02:28:37