简体   繁体   English

G1不处理软引用

[英]G1 doesn't process soft references

Here is my simple gc test: 这是我简单的gc测试:

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) {}
  }
}

Using these args (G1 enabled): 使用这些args(启用G1):

java -Xmx2G -Xms2G -XX:MaxPermSize=128m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps 
-XX:+PrintAdaptiveSizePolicy -Xloggc:jvm.log -XX:+UseG1GC 
-XX:InitiatingHeapOccupancyPercent=5 Main

I grep the output: 我grep输出:

grep -E "(Full|GC cleanup)" jvm.log

and get something like this: 得到这样的东西:

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]

It seems that soft references were collected during ParallelGc's full collections while concurrent collections were almost useless. 似乎在ParallelGc的完整集合期间收集了软引用,而并发集合几乎无用。 Heap dumps from VisualVm also prove this version. VisualVm的堆转储也证明了这个版本。

Do I miss something or it is a bug in G1? 我错过了什么,或者它是G1中的一个错误?

Checked on 1.7.0_51-b13 and 1.8.0_45-b15 x64. 检查1.7.0_51-b13和1.8.0_45-b15 x64。

Perhaps you are confusing with weak references? 也许你对弱引用感到困惑?

The GC is not forced to collect soft references, unless it finds itself under severe memory pressure. GC不会被迫收集软参考,除非它发现自己处于严重的内存压力下。

See here for more information. 有关更多信息,请参见此处

In particular, notice the following quote from the documentation: 特别注意文档中的以下引用:

Soft reference objects, which are cleared at the discretion of the garbage collector in response to memory demand. 软参考对象,由垃圾收集器根据内存需求自行决定清除。

The only real guarantee the documentation offers is as follows: 文档提供的唯一真正保证如下:

All soft references to softly-reachable objects are guaranteed to have been cleared before the virtual machine throws an OutOfMemoryError. 在虚拟机抛出OutOfMemoryError之前,保证已清除对软可访问对象的所有软引用。

There is -XX:SoftRefLRUPolicyMSPerMB= (default=1000) that governs the collection rate of soft references. -XX:SoftRefLRUPolicyMSPerMB= (默认值= 1000),用于管理软引用的收集率。 Lower values make it collect them faster. 较低的值使其更快地收集它们。

I don't know how it interacts with G1's regions. 我不知道它是如何与G1的区域相互作用的。 It's possible that some regions are rarely touched and thus their soft references don't get taken into account. 某些地区可能很少被触及,因此不会考虑它们的软参考。

As @sstan mentioned WeakReferences may offer somewhat more predictable behavior at the expense of much shorter lifetimes of the references. 正如@sstan所提到的,WeakReferences可能会提供一些更可预测的行为,但代价是引用的寿命要短得多。


Another problem is that you do not clear the list of nulled-out softreference objects. 另一个问题是您没有清除已排除的软引用对象列表。 If you register the refs with a reference queue , poll that queue during after the sleep(1000) for references and remove them from the list you should not run out of memory. 如果您使用引用队列注册refs,请在sleep(1000)之后轮询该队列以进行引用,并将其从列表中删除,这样您就不应该耗尽内存。 For faster lookup a set might be more suitable than a list. 为了更快地查找,集合可能比列表更合适。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM