静态数据的java短期与长期
我了解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;
}
这将只创建一次列表。这个单一的列表实例最终将进入终身一代。由于这是一个相当大的应用程序,在许多地方使用这种设计模式将意味着在长期使用的一代中有很多这样的静态列表,从而增加应用程序的内存使用
如果我们遵循每次创建并返回一个新列表的模式,那么在被垃圾收集之前,这个列表将永远不会离开伊甸园。这将涉及更多的工作——必须创建和填充列表,并进行垃圾收集——但由于列表不会持续很长时间,所以我们总体上会使用更少的内存
这个问题本质上更具学术性,因为两种模式都适用。存储静态列表将显著增加内存使用量,而每次创建列表将显著增加工作负载。使用哪种模式可能取决于很多因素——列表的使用频率、应用程序的内存压力等等。你们会选择哪种模式,安迪,为什么
# 1 楼答案
当没有真正的需求时,它会占用更多的空间。如果有一种用法,它也是一样的。但是如果你有多个副本,静态版本的效率会更高
通常情况下,杀死你的不是最好的情况,而是最坏的情况。在最坏的情况下,会有大量的人吗?数以百万计的?收藏的副本
# 2 楼答案
正如Peter Lawrey所指出的,在非静态的情况下,当GC等待完成它的任务时,有时您将使用比所需多得多的内存
我会专注于更具可读性的内容。对我来说,番石榴在
static final
字段中的ImmutableList.of
表示这些数据不会立即改变(或者
Collections.unmodifiableList(Arrays.asList(...))
如果你不想要番石榴)