我正在重构一个名为ConfigNode
的类,它存储了50个“属性”。每个属性都是它自己的对象。所有属性都是可选的,大部分时间都没有设置。
目前,编写类是为了在实例化时,所有50个属性也被实例化。当您创建一百万个Config
对象时,Java告诉我我正在使用2.5 GB的内存。当我注释掉属性实例化时,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() {
//
}
}
答案 0 :(得分:2)
Guava的Suppliers
库可以为你做所有延迟加载的逻辑(包括线程安全,你的例子没有)。
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();
}
(请注意,这是一个番石榴供应商,而不是java.util.function.Supplier
)
如果您还没有使用Java 8,那么这将更加冗长:
private Supplier<NodeProperty> propOneSupplier =
Suppliers.memoize(
new Supplier<NodeProperty>()
{
@Override
public NodeProperty get()
{
return new NodeProperty(...);
}
});
答案 1 :(得分:0)
方法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类设为单例更好。类似的东西:
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();
}
}
}
}
}