java - 优化变量声明原语与空对象

标签 java memory optimization

我有一个名为Location的类,它有两种类型的信息,一种是nodeID(整数),另一种是diskPosition(长整型)。 我的应用程序需要创建此 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);
        }
    }
}

最佳答案

答案取决于您创建的实例数量以及 nodeIDdiskPos 值的分布。让我们看看这些数字,假设是 32 位 JVM(或带有指针压缩的 64 位)。这些值可能仍然与您的 JVM 实现不匹配,但它们对于 HotSpot 来说应该是正确的。

使用 intlong 时,Location 实例占用 24 个字节。对于IntegerLong,这取决于情况。 Location 实例占用 16 个字节,IntegerLong 对象可能各占用 16 个字节,除非它们是共享的。如果,正如您所说,其中一个在大多数情况下保持 -1(或 null),则不占用内存,因此总共占用 16 或 32 个字节。是否共享IntegerLong 实例取决于值和JVM 设置。由于 diskPos 需要很长,因此实例不太可能被缓存。

所以答案是:原语 = 24 字节,装箱很可能是 32 字节。保持原语。

如果您使用实现通用接口(interface)的不同类,您可以将每个实例的内存消耗降至 16 字节。我不会这样做是为了节省内存(在您注意到之前您需要数百万个实例),而是为了更具可读性的代码,因为对于字段 -1 之一, Location 实际上是一种联合类型,并且您可能有这样的代码:

if (location.getNodeId() >= 0) {
    // do something with node id
} else {
    // do something with diskPos
}

更加面向对象的设计可以让您将不同的行为合并到相应的类中。

关于java - 优化变量声明原语与空对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23488243/

相关文章:

java - 如何从文件中逐行读取,在第二个空格后拆分,以便将名称和分数分开?

java - Neo4j - 没有这样的 ServerPlugin 错误

javascript - 如何使用 REST api 删除带有 angularjs 的集合?

c++ - "for(;;)"比 "while (true)"快吗?如果不是,人们为什么要使用它?

c++ - 优化器优化 C++ 或程序集的作用是什么

java - flink+卡夫卡: getHostnamePort

Powershell 作业内存消耗问题

java - 无法为对象堆保留足够的空间来启动 JVM

c++ - Present() 中奇怪的 Direct3D 内存行为

swift - 淡入和淡出 SKLabelNode 的最佳方式