ピーターDolbergによって回答に基づいているとVisualVM OQLコンソールで使用することができ、次の
それが作成または更新各文字列のすべての文字列のインスタンス上とのため
map()
コールを使用して起動
var counts={};
var alreadyReturned={};
filter(
sort(
map(heap.objects("java.lang.String"),
function(heapString){
if(! counts[heapString.toString()]){
counts[heapString.toString()] = 1;
} else {
counts[heapString.toString()] = counts[heapString.toString()] + 1;
}
return { string:heapString.toString(), count:counts[heapString.toString()]};
}),
'lhs.count < rhs.count'),
function(countObject) {
if(! alreadyReturned[countObject.string]){
alreadyReturned[countObject.string] = true;
return true;
} else {
return false;
}
}
);
配列counts
のオブジェクトです。各オブジェクトはstring
とcount
のフィールドを持ちます。
結果の配列には、文字列インスタンスごとに1つのエントリが含まれます。各エントリには、同じ文字列の前のエントリより1つ大きい値のcount
が含まれます。 結果はcount
フィールドでソートされ、その結果は次のようなものになります。
{
count = 1028.0,
string = *null*
}
{
count = 1027.0,
string = *null*
}
{
count = 1026.0,
string = *null*
}
...
を(私のテストで文字列"*null*"
が最も一般的でした)。
最後のステップは、各文字列の最初の出現に対してtrueを返す関数を使用してこれをフィルタリングすることです。配列を使用して、どの文字列が既に含まれているかを追跡します。
問題をうまく解決していただきありがとうございます。 oqlは何とか使いにくいです。それはすべて1つの機能で起こらなければならない... – paweloque
うわー、それはjvisualvmが強力であることを知らなかった。私はいくつかの文字列のための高いカウント値を見つけました - あなたのコードはガベージ(参照文字列ではない)を除外しますか? – Jan
"heap.objects"を使用して、ヒープ上のすべてのjava.lang.Stringオブジェクトを検索します。参照されていないStringを除外するフィルタリングはありません。しかし、ヒープ・ダンプがどのように生成されたかによって、JVMは完全なGCを前もって実行している可能性があります。その場合、参照されていないStringはすべて削除されていて、ヒープ・ダンプには含まれていません。 –