1

我了解 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;
}

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

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

这个问题本质上更具学术性,因为任何一种模式都可以。存储静态列表只会增加少量的内存使用,而每次创建列表只会增加少量的工作量。使用哪种模式可能取决于许多因素 - 使用列表的频率、应用程序承受的内存压力等。你们会针对哪种模式,为什么?

4

2 回答 2

4

存储静态列表将增加内存使用量微不足道

当没有真正需要它时,它将使用更多空间。如果有一种用法,那将是相同的。但是如果你有多个副本,静态版本的效率更高。

通常,杀死你的不是最好的情况,而是最坏的情况。在最坏的情况下会有大量的?数百万?集合的副本。

于 2012-09-26T19:10:52.773 回答
0

正如 Peter Lawrey 指出的那样,在非静态情况下,有时您会在 GC 等待执行其操作时使用比必要更多的内存。

我会专注于更具可读性的内容。对我来说,番石榴ImmutableList.of在一个static final领域立即表示这些数据不会改变。

(或者Collections.unmodifiableList(Arrays.asList(...))如果你不想要番石榴)

于 2012-09-26T19:53:14.297 回答