[英]Build org.joda.time.DateTime with java.time.LocalDate and java.time.LocalTime or java.time.LocalDateTime
[英]Memory consumption java.util.Date vs java.time.LocalDate vs org.joda.time.DateTime
我想知道内存消耗
java.util.Date
java.time.LocalDate
org.joda.time.DateTime
我需要创建一堆具有一些日期的对象,今天它们是很长的时间戳,但这不太好,并且由于我需要日期而在另一侧创建了CPU负载。
所以我的问题是:是否有可用的统计数据? 大概如何衡量这种事情?
我不用担心,您需要数百万个对象才能真正在服务器上发挥作用。
但是,如果您真的想知道,则可以查看实现以查看每个对象的字段,每个父对象的字段等以及每个引用的对象的字段。 您可以累加每个字段使用的字节数+对象引用的大小(4或8个字节,取决于JVM)加上Java规范中描述的填充。
或者,您可以使用第3方库(例如java.sizeOf)为您完成此操作。
但是,快速浏览一下您要查询的类的代码,以下是这些字段:
日期:
private transient long fastTime;
/*
* If cdate is null, then fastTime indicates the time in millis.
* If cdate.isNormalized() is true, then fastTime and cdate are in
* synch. Otherwise, fastTime is ignored, and cdate indicates the
* time.
*/
private transient BaseCalendar.Date cdate;
long
+对具有其自己的字段等的其他类的引用。但是,经过大量的代码阅读, cdate
几乎都是null
因此我们只需要计算对象引用的大小(为null),我认为这不会膨胀使用32位或64位时,对象的大小超出24字节填充的范围,请使用压缩的Ops,它会尝试使用4字节引用而不是8字节引用。 (我认为这是Java 8的默认设置),因此我们可以忽略它。
本地日期:
/**
* The year.
*/
private final int year;
/**
* The month-of-year.
*/
private final short month;
/**
* The day-of-month.
*/
private final short day;
因此, int+short+short
的大小与long
相同,但是您必须考虑保留的每个LocalDate
引用的内存。
约会时间:
private long iMillis;
private Chronology iChronology;
这也是long
+对其他占用内存的对象的引用。
使用SizeOf
当我创建每个对象的实例并在64位Java 8 JVM上对它们使用java.sizeOf时,我得到了以下内存大小(以字节为单位):
javaDate = 24
localDate = 24
dateTime = 16928
如您所见,jodatime的所有支持类都占用大量内存。 但是,当您拥有其他实例时,其中的大部分将被重用。
因此,如果您的long
不在类中,我将继续使用它们。 但是,如果您将long
封装在一个类中,或者甚至使用Long
,则LocalDate
似乎是最好的,因为它的内存量相同,加上所有支持的类用于转换/时区等。我不会使用Date
因为该类是可变的,应该被认为已弃用。
最有效 以长值存储:8个字节(此外,作为参数传递时,它是不可变的)
Java.util.Date
VM 64位:对象的12个+长值的8个+引用BaseCal.Date的4个= 24字节
Sun VM 32位:8 + 8 + 4 = 20 + 4填充= 24字节
(不可推荐,因为没有任何优势,可变,需要更多内存)
有实现(IBM嵌入式Java,其中Date仅具有一个字段)(这将是最少16个字节)
本地日期
VM 64位:12 + 4 + 2 + 2 = 20 +4填充= 24字节
VM 32位:8 + 4 + 2 + 2 = 16字节;
在Android Dalvik上:12 + 4 + 4 + 4 = 24字节
乔达日期时间
VM 64位:12 + 8 + 4,用于编年表:= 24字节
VM 32位:8 + 8 + 4,用于编年表参考+ 4个填充= 24字节
大概如何衡量这种事情? 在Sun VM上,您可以使用MAT,它使用Sun VM的特殊功能。 (请参阅Szymon Krawczyk的答案)在其他VM上,它很难衡量,而且我所见的任何代码(基于堆大小的MemoryTestBench,gc调用等)在某些情况下均会失败,从而导致内存消耗为负。
最正确的方法是自己计算:
在VM上分配空对象需要8字节的Sun VM 32或12 Sun VM64 + Dalvik +对象大小始终填充为8字节的下一个倍数。
领域
参考字段需要4个字节。 int:4个字节,
长8
短2(在Dalvik上为4),
布尔1字节(Sun),4字节Dalvik;
数组是一个对象+一个int字段(array.length)= 16字节,Dalvik除外,在Dalvik上它出于奇怪的原因需要20字节(如果没有元素则需要+ 4填充)= 24
根据joda-time的说法,它们提供了处理日期的最佳方法:
http://www.joda.org/joda-time/ http://www.joda.org/joda-time/faq.html
创建Joda-Time是为了从根本上改变Java中的日期和时间处理。 JDK类Date和Calendar的设计很糟糕,有很多错误,并且效果奇特。 这是我们开发和使用Joda-Time的一些原因:
根据个人经验,我同意他们的观点。 但是,您可以在运行应用程序时使用jvisualvm (jdk / bin)分析工具更好地对其进行分析。
我可以发表评论,但是就内存使用而言,您可以通过执行以下操作来获取正在运行的应用程序的内存转储(堆转储): jmap -dump:format=b,file=cheap.bin <pid>
如果使用ECLIPSE,则当然要安装MAT ,然后在eclipse中打开该文件并比较对象大小。 我用它来找出带有servlet和Tomcat服务器的Web应用程序中的内存泄漏,这真的很有用
但是,如果您对此不感兴趣,请查看该问题以获取操作系统级别的系统信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.