我正在重构一个名为ConfigNode
的类,该类存储50个"属性"。每个属性都是自己的对象。所有属性都是可选的,大多数情况下,其中许多属性都没有设置。
目前,类的编写方式是,当它被实例化时,所有50个属性也都被实例化。当您创建一百万个Config
对象时,Java告诉我正在使用2.5吉的内存。当我注释掉属性实例化时,Java说我使用的是300 MB。
我使用的基准代码是
Runtime.getRuntime().gc();
// do my stuff
Runtime.getRuntime().gc();
long memory = Runtime.getRuntime().totalMemory();
System.out.println("Memory used: " + memory / 1000000 + " MB");
因此,我正在考虑重写类,以便在访问属性时延迟加载属性,但必须编写类似的内容
// This is probably not thread safe, so it could be even more verbose
public NodeProperty propOne() {
if (propOne == null) {
propOne = new NodeProperty( ... )
}
return propOne
}
然后对所有属性执行此操作似乎有点冗长。Java中有什么可以帮助我减少必须编写的代码量(从而减少维护)吗?
以下是NodeConfig看起来像的样子
public class NodeConfig {
public NodeProperty pVersion = new NodeProperty( "Spec Version", Status.REQUIRED, Visibility.HIDDEN);
public NodeProperty pTwoWay = new NodeProperty( "Two way", Status.OPTIONAL, Visibility.VISIBLE );
public NodeProperty pBinary = new NodeProperty( "Binary mode", Status.OPTIONAL, Visibility.HIDDEN);
// more properties
public NodeConfig() {
//
}
}
Guava的供应商库可以为您完成所有延迟加载的逻辑(包括线程安全,而您的示例没有)。
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
private Supplier<NodeProperty> propOneSupplier =
Suppliers.memoize(() -> new NodeProperty(...));
public NodeProperty propOne() {
return propOneSupplier.get();
}
方法1
以下是在给定NodeConfig
代码的情况下可以使用的另一种方法:公共类NodeConfig{
public NodeProperty pTwoWay;
public NodeProperty pBinary;
// more properties
public NodeConfig() {
//
}
public NodeProperty getProperty(NodePropertyEnum nodeProp) {
switch(nodeProp) {
case TWO_WAY:
if (pTwoWay != null) {return pTwoWay;}
pTwoWay = new NodeProperty( "Two way", Status.OPTIONAL, Visibility.VISIBLE );
case BINARY_MODE:
if (pBinary != null) {return pBinary;}
pBinary = new NodeProperty( "Binary mode", Status.OPTIONAL, Visibility.VISIBLE);
// other cases
default:
throw new IllegalArgumentException();
}
}
}
方法2
看起来像是Singleton
设计模式的案例。与其检查propOne
实例是否为null
,不如将所有Property类设置为singleton。类似于:
public class NodeProperty {
private static volatile NodeProperty instance = null;
private NodeProperty() {
// instantiatin logic
}
public NodeProperty getInstance() {
if(instance == null) {
synchronized(NodeProperty.class) {
if(instance==null) {
instance = new NodeProperty();
}
}
}
}
}