我有一个名为Location的类,它有两种类型的信息,一个是nodeID(一个整数),另一个是diskPosition(long)。 我的应用程序需要创建此Location类的许多对象,但大多数时候我会在类Location中为这两个变量之一分配一个默认值(比如-1)。
我的问题是“我应该将这些nodeID和diskPosition声明为Integer和Long并指定默认值null而不是将它们保持为原始值并将默认值指定为-1”“
我担心的是我的Location对象占用的内存量,我希望将其最小化。
以下是Location类的代码片段:
public class Location
{
private int nodeID = -1;
private long diskPos = -1;
public Location(long diskPos)
{
this.diskPos = diskPos;
}
public Location(Node node)
{
this.nodeID = node.getNodeID();
}
// Test main method to elaborate usage of Location object
public void main(String[] args)
{
Map<Integer, Location> cellIDToLocationMap = new HashMap<Integer, Location>();
// Consider there is a list of nodes which is obtained from somewhere
List<Node> nodeList = getNodeList();
Location loc = null;
for (int i = 1; i <= 10000; i++)
{
if (i % 2 == 0)
loc = new Location(nodeList.get(i));
else
loc = new Location(i);
// Put in map
cellIDToLocationMap.put(i, loc);
}
}
}
答案 0 :(得分:1)
答案取决于您创建的实例数以及nodeID
和diskPos
值的分布情况。让我们看看这些数字,假设一个32位JVM(或指针压缩的64位)。这些值可能仍然与您的JVM实现不匹配,但它们对于HotSpot应该是正确的。
使用int
和long
Location
实例需要24个字节。对于Integer
和Long
,它取决于。 Location
个实例需要16个字节,而Integer
和Long
个对象可能各占16个,除非它们是共享的。如果如你所说的那样,其中一个在大多数时间内保持-1(或null
),那就不占用内存,因此总共需要16或32个字节。是否共享Integer
或Long
个实例取决于值和JVM设置。由于diskPos
需要很长,因此实例不太可能被缓存。
所以答案是:primitive = 24个字节,盒装很可能是32个字节。坚持原始。
如果您使用实现公共接口的不同类, 可以将每个实例的内存消耗降低到16个字节。我不会这样做是为了节省内存(在你注意之前你需要数百万个实例),但是对于更易读的代码,因为,在字段-1之一中,Location
实际上是一个联合类型,你可能有这样的代码:
if (location.getNodeId() >= 0) {
// do something with node id
} else {
// do something with diskPos
}
更面向对象的设计可以让您将不同的行为合并到各自的类中。