Java中“Date”对象的大小

5
如何有效地确定我的内存中Date对象的大小?
最初,我阅读了这篇文章link,其中讨论了日期对象的9个字节。
当我找到这个链接时,它谈到了内存中日期对象的32个字节!!! Date Object Size in Memory 请帮忙。
思考这些线路的原因: 我正在将某个类的数百万个对象加载到内存中进行计算。该类中的一个变量是Date对象。我可以将值存储为long,但这需要代码中的小问题。我考虑尽可能减少内存占用。为此,我需要知道每种情况的确切内存要求,以便对其进行调用。

6
你可以解释一下你需要关心的问题吗? - John3136
2
堆空间中的消耗 != 序列化大小,https://dev59.com/2nVC5IYBdhLWcg3wixw0 - jdphenix
@John3136 已添加相同内容。谢谢。 - LPD
如果您需要加载数百万个日期对象,也许您会使用整数值来满足您的需求,例如最大日期范围或时间分辨率等。 - Erdinç Taşkın
3个回答

2

回答这个问题最简单的方法是查看java.util.Date的源代码。

它只有两个非静态字段(Java 1.7.0_55):

private transient long fastTime;
private transient BaseCalendar.Date cdate;

long占用8个字节的内存,cdate是一个对象引用,大小为4个字节。因此,总共占用12个字节

如果实例化cdate,它可能需要更多字节的内存。但是,如果你查看构造函数,有时候它甚至不会被触及,在其他情况下,它将在构造函数结束时被设为null,因此最终结果也是12个字节

这只是用于创建一个Date。如果你调用Date.toString()等方法,那么将会创建并将对象存储到cdate字段中,此对象将不会被清除。因此,如果你在Date上调用某些方法,其内存使用量将增加。

注意:在64位JVM上,对象引用可能为64位长,此时内存使用量将为16个字节。

注意 #2:还要注意,这仅是Date对象本身的内存使用量。最有可能你会把它的引用存储在某个地方,例如数组、列表或其他类的字段中,这将需要额外的4个字节(在64位JVM上可能是8个字节)。


你看的是哪个版本的Java源代码? - Luiggi Mendoza
@LuiggiMendoza Java 1.7.0_55。 - icza

2

您的第一个链接讨论的是序列化后的大小,而您所说的是内存中的大小。这就是为什么它们的大小不同。

根据您的链接,保存长整型需要9个字节。

根据您的第二个链接,在内存中,长整型和其他允许您使用日期的对象需要32个字节。


1
这取决于您的实现方式,您想要做什么以及如何定义和测量大小。例如,
public static void main(String[] args) {
    Date d = new Date();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    try (ObjectOutputStream oos = new ObjectOutputStream(baos);) {
        oos.writeObject(d);
        oos.flush();
    } catch (Exception e) {
        e.printStackTrace();
    }
    byte[] written = baos.toByteArray();
    System.out.println(written.length);
}

输出

46

在编程中,使用原始类型long比任何对象类型(包括Date)都要占用更少的内存。这就是Java包含原始类型的根本原因。最后,使用Calendar的实例并将值保持为long应该能够让您灵活地最小化代码更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接