对于静态数据,短命与长寿

时间:2012-09-26 18:58:58

标签: java garbage-collection

我理解HotSpot JVM使用的分代垃圾收集是如何工作的。我们有一个方法,它返回一个静态数据列表,沿着

public List<String> getList() {
    List<String> ret = new ArrayList<String>();
    ret.add("foo");
    ret.add("bar");
    return ret;
}

我正在考虑将其重写为

private static List<String> list = null;
...
public List<String> getList() {
    if (list == null) { .. initialize here .. }
    return list;
}

这只会创建一次列表。这个单一列表实例最终将进入终身代。由于这是一个相当大的应用程序,在许多地方使用这种设计模式意味着在终身代中有很多这些静态列表 - 增加应用程序的内存使用量。

如果我们每次都遵循创建和返回新列表的模式,那么列表在被垃圾收集之前永远不会从伊甸园中删除。将涉及更多的工作 - 必须创建和填充列表,并在垃圾收集工作 - 但我们将使用更少的内存,因为列表不会持续很长时间。

这个问题在本质上更具学术性,因为这两种模式都有效。存储静态列表会使内存使用量增加一个微不足道的数量,每次创建列表会使工作量增加不显着。使用哪种模式可能取决于许多因素 - 列表的使用频率,应用程序的内存压力等等。您将针对哪种模式,以及为什么?

2 个答案:

答案 0 :(得分:4)

  

存储静态列表会使内存使用量增加不显着的数量

在没有真正需要时会占用更多空间。如果有一种用法,它将是相同的。但是,如果您有多个副本,静态版本会更有效。

通常这不是杀死你的最好的情况,这是最糟糕的情况。在最坏的情况下会有大数?数百万?该系列的副本。

答案 1 :(得分:0)

正如彼得·劳瑞所指出的那样,在非静态的情况下,有时你会在GC等待做的事情上使用比必要更多的内存。

我会专注于更具可读性的东西。对我来说,ImmutableList.of字段中的番石榴static final表示此数据不会立即改变。

(如果你不想要番石榴,可以Collections.unmodifiableList(Arrays.asList(...))