即使没有在构造函数中使用:
public Neuron(float[] connection, float bias) {
this.connection = connection;
this.bias = bias;
}
所有实例字段(所以name 和propability 也是)在构造函数被执行之前被初始化。
这些使用默认值初始化:
private String name; // null
private float propability; // 0F
但是这些默认值没有任何成本(null 和 0)。
所以不要为此烦恼。
我有一个类,我想使用大约十到十万个。
因此,我不会不必要地浪费内存位置。
如果是的话,我还有其他选择吗(除了让它们成为自己的
class) 来减少内存使用?
如果这些对象有一些公共数据,请在实例之间共享这些数据。
依赖共享数据不变性的flightweight 模式说明了这种做法。
The String objects use that.
完全同意 GhostCat 的说法:即使不使用的字段也会消耗内存。不是很多,但他们消耗。但这适用于 Java 中的许多类。
例如,我们不会用数组替换所有列表,因为数组通常消耗较少。我们会这样做,因为在我们的特定情况下,列表内存占用是一个真正的担忧。
总而言之,在优化和改变我们的设计之前,我认为首先要做的是衡量并确定您是否要优化以获得金牌或坚果。
使用您的实际代码和产生 100 万个神经元的 main() 方法,我注意到大约消耗了 131 Mo:
public static void main(String[] args) {
long beforeUsedMem=Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
List<Neuron> neurons = new ArrayList<>();
for (int i = 0; i < 1_000_000; i++) {
neurons.add(new Neuron(new float[] { 0, 15.4F, 1.1F, 2.1F, 3.4F, 4.5F, 8.9F, 158.9F, 8648.9F, 80.9F, 10.9F, 1450.9F, 114.9F, 14.5F, 4444.4F }, 1.9F));
}
long afterUsedMem=Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
long actualMemUsed=(afterUsedMem-beforeUsedMem)/1_000_000;
System.out.println(actualMemUsed + " Mo");
}
客观地说,它很低。
通过删除未使用的字段,它大约下降到 124 Mo(少 7 个月):
private String name;
private float propability;
131 Mo 和 124 Mo 对于这么多创建的对象来说是相当低的值:100 万。
如果该类声明了十几个未使用的字段,情况会有所不同。不会浪费任何可忽略的内存量,并且总体而言,该类在设计方面根本不清楚:内聚度低。
但事实并非如此。