這裏是我的簡單的GC測試:G1不處理軟引用
public class Main {
static class Data {
public long[] l = new long[100];
}
static List<SoftReference<Data>> list = new ArrayList<>();
public static void main(String[] args) {
long i = 0;
while (true) {
list.add(new SoftReference<>(new Data()));
++i;
if (i % 1000 == 0) {
sleep(1);
if (i % 1_000_000 == 0)
sleep(1000);
}
}
}
static void sleep(long millis) {
try { Thread.sleep(millis); } catch (InterruptedException ignored) {}
}
}
使用這些ARGS(啓用G1):
java -Xmx2G -Xms2G -XX:MaxPermSize=128m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
-XX:+PrintAdaptiveSizePolicy -Xloggc:jvm.log -XX:+UseG1GC
-XX:InitiatingHeapOccupancyPercent=5 Main
我用grep輸出:
grep -E "(Full|GC cleanup)" jvm.log
並得到像這樣的東西:
0.564: [GC cleanup 277M->277M(2048M), 0.0009922 secs]
0.879: [GC cleanup 443M->442M(2048M), 0.0009396 secs]
1.676: [GC cleanup 859M->856M(2048M), 0.0008681 secs]
3.530: [GC cleanup 1324M->1320M(2048M), 0.0012422 secs]
4.838: [GC cleanup 1711M->1707M(2048M), 0.0010601 secs]
6.334: [Full GC 2047M->102M(2048M), 1.2659685 secs]
8.322: [GC cleanup 534M->534M(2048M), 0.0009528 secs]
11.250: [GC cleanup 1460M->1450M(2048M), 0.0011207 secs]
13.499: [Full GC 2046M->512M(2048M), 1.3534848 secs]
似乎在ParallelGc的完整集合中收集了軟引用,而併發集合幾乎沒用。從VisualVm堆轉儲也證明了這個版本。
我錯過了什麼,或者它是G1中的錯誤?
檢查1.7.0_51-b13和1.8.0_45-b15 x64。
軟引用將表現得非常奇怪和不確定。強迫GC對他們做任何事情都很難或不可能。 –
看來這個問題已經存在於Oracle bugtracker中,它不會很快關閉:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6912889 –