[英]Memory consumption java.util.Date vs java.time.LocalDate vs org.joda.time.DateTime
I was wondering about the memory consumption by 我想知道内存消耗
java.util.Date
java.time.LocalDate
org.joda.time.DateTime
I need to create a bunch of objects which have some Dates, today they are timestamps as longs but this does not so nice and creates CPU load on the other side because I need the dates. 我需要创建一堆具有一些日期的对象,今天它们是很长的时间戳,但这不太好,并且由于我需要日期而在另一侧创建了CPU负载。
So my question is: Is there any statistic available? 所以我的问题是:是否有可用的统计数据? How to measure such things probably? 大概如何衡量这种事情?
I wouldn't worry about it, you would need millions of Objects for this to really make a difference on a server. 我不用担心,您需要数百万个对象才能真正在服务器上发挥作用。
But if you really want to know, you can look at the implementations to see the fields of each object, and the fields of each parent object etc and the fields of each referenced object). 但是,如果您真的想知道,则可以查看实现以查看每个对象的字段,每个父对象的字段等以及每个引用的对象的字段。 You can add up the number bytes used by each field + the size of an object reference (4 or 8 bytes depending on JVM) plus padding described in the Java spec. 您可以累加每个字段使用的字节数+对象引用的大小(4或8个字节,取决于JVM)加上Java规范中描述的填充。
Or you can use 3rd party libraries such as java.sizeOf which will do this for you. 或者,您可以使用第3方库(例如java.sizeOf)为您完成此操作。
But taking a quick look at the code of the classes you asked about, here are the fields: 但是,快速浏览一下您要查询的类的代码,以下是这些字段:
Date: 日期:
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
+ reference to other class which has its own fields etc. However, after lots of code reading, cdate
is almost alwasy null
so we only have to count the size of the object reference (to null) which I think won't bloat up the size of the object beyond the padding of 24 bytes when using a 32-bit or if on 64 bit, using compressed Ops which tries to use 4 byte references instead of 8 when possible. long
+对具有其自己的字段等的其他类的引用。但是,经过大量的代码阅读, cdate
几乎都是null
因此我们只需要计算对象引用的大小(为null),我认为这不会膨胀使用32位或64位时,对象的大小超出24字节填充的范围,请使用压缩的Ops,它会尝试使用4字节引用而不是8字节引用。 (I think this is default on Java 8) so we can ignore it. (我认为这是Java 8的默认设置),因此我们可以忽略它。
LocalDate: 本地日期:
/**
* The year.
*/
private final int year;
/**
* The month-of-year.
*/
private final short month;
/**
* The day-of-month.
*/
private final short day;
So int+short+short
takes the same size as long
but you have to account for the memory of each LocalDate
reference you keep around. 因此, int+short+short
的大小与long
相同,但是您必须考虑保留的每个LocalDate
引用的内存。
Datetime: 约会时间:
private long iMillis;
private Chronology iChronology;
Which is also long
+ object ref to other object that takes up memory. 这也是long
+对其他占用内存的对象的引用。
Using SizeOf 使用SizeOf
When I created an instance of each object and used java.sizeOf on them on my 64bit Java 8 JVM I got the following memory sizes (in bytes): 当我创建每个对象的实例并在64位Java 8 JVM上对它们使用java.sizeOf时,我得到了以下内存大小(以字节为单位):
javaDate = 24
localDate = 24
dateTime = 16928
As you can see jodatime takes up a lot of memory with all of its supporting classes. 如您所见,jodatime的所有支持类都占用大量内存。 Much of it will be reused when you have other instances though. 但是,当您拥有其他实例时,其中的大部分将被重用。
Therefore, I would go with keep using your long
s if they aren't wrapped in a class. 因此,如果您的long
不在类中,我将继续使用它们。 But if you are wrapping your long
in a class, or even using Long
, LocalDate
seems best since it's the same amount of memory plus all the supporting classes for converting/ timezones etc. I would not use Date
since that class is mutable and should be considered deprecated. 但是,如果您将long
封装在一个类中,或者甚至使用Long
,则LocalDate
似乎是最好的,因为它的内存量相同,加上所有支持的类用于转换/时区等。我不会使用Date
因为该类是可变的,应该被认为已弃用。
Most efficient; 最有效 storing in a long value: 8 bytes (further it is immutable when passed as param) 以长值存储:8个字节(此外,作为参数传递时,它是不可变的)
Java.util.Date Java.util.Date
VM 64 bit: 12 for the object +8 for long value + 4 for ref to BaseCal.Date = 24 bytes VM 64位:对象的12个+长值的8个+引用BaseCal.Date的4个= 24字节
Sun VM 32 bit: 8 + 8 + 4 = 20 + 4 padding = 24 bytes Sun VM 32位:8 + 8 + 4 = 20 + 4填充= 24字节
(Not recomendable since has not any advantage, is mutable, needs more memory) (不可推荐,因为没有任何优势,可变,需要更多内存)
There are implementation (IBM Embedded Java where Date has only one field) (That would be 16 bytes minimal) 有实现(IBM嵌入式Java,其中Date仅具有一个字段)(这将是最少16个字节)
LocalDate 本地日期
VM 64 bit: 12 + 4 + 2 + 2 = 20 +4 padding = 24 bytes VM 64位:12 + 4 + 2 + 2 = 20 +4填充= 24字节
VM 32 bit: 8 + 4 + 2 + 2 = 16 bytes; VM 32位:8 + 4 + 2 + 2 = 16字节;
On android Dalvik: 12 + 4 + 4 + 4 = 24 bytes 在Android Dalvik上:12 + 4 + 4 + 4 = 24字节
joda DateTime 乔达日期时间
VM 64 bit: 12 + 8 + 4 for the reference to Chronology: = 24 bytes VM 64位:12 + 8 + 4,用于编年表:= 24字节
VM 32 bit: 8 + 8 + 4 for the reference to Chronology + 4 padding = 24 bytes VM 32位:8 + 8 + 4,用于编年表参考+ 4个填充= 24字节
How to measure such things probably? 大概如何衡量这种事情? On Sun VM you can use MAT which uses a special featuire of the Sun VM. 在Sun VM上,您可以使用MAT,它使用Sun VM的特殊功能。 (see the answer of Szymon Krawczyk) On other VM its is difficult to measure and any code which I have seen (MemoryTestBench based on heap size, gc calls etc.) failed in some situations, giving negative memory consumption. (请参阅Szymon Krawczyk的答案)在其他VM上,它很难衡量,而且我所见的任何代码(基于堆大小的MemoryTestBench,gc调用等)在某些情况下均会失败,从而导致内存消耗为负。
The most correct way is to count it yourself: 最正确的方法是自己计算:
Depening on the VM an empty objects needs 8 byte Sun VM 32, or 12 Sun VM64 + Dalvik + the object size always is padded to next multiple of 8 bytes. 在VM上分配空对象需要8字节的Sun VM 32或12 Sun VM64 + Dalvik +对象大小始终填充为8字节的下一个倍数。
Fields 领域
A reference field needs 4 bytes. 参考字段需要4个字节。 int: 4 bytes, int:4个字节,
long 8, 长8
short 2 (or 4 on Dalvik), 短2(在Dalvik上为4),
boolean 1 byte (Sun) , 4 bytes Dalvik; 布尔1字节(Sun),4字节Dalvik;
An array is an object + an int field (array.length) = 16 bytes, except on Dalvik where for strange reasons it needs 20 bytes ( + 4 padding if no elemens) = 24 数组是一个对象+一个int字段(array.length)= 16字节,Dalvik除外,在Dalvik上它出于奇怪的原因需要20字节(如果没有元素则需要+ 4填充)= 24
According to joda-time, they offer the best way to work with dates: 根据joda-time的说法,它们提供了处理日期的最佳方法:
http://www.joda.org/joda-time/ http://www.joda.org/joda-time/faq.html http://www.joda.org/joda-time/ http://www.joda.org/joda-time/faq.html
Joda-Time has been created to radically change date and time handling in Java. 创建Joda-Time是为了从根本上改变Java中的日期和时间处理。 The JDK classes Date and Calendar are very badly designed, have had numerous bugs and have odd performance effects. JDK类Date和Calendar的设计很糟糕,有很多错误,并且效果奇特。 Here are some of our reasons for developing and using Joda-Time: 这是我们开发和使用Joda-Time的一些原因:
And by personal experience, I agree with them. 根据个人经验,我同意他们的观点。 But, you can analyse it better using jvisualvm (jdk/bin) profiling tool, while running your application. 但是,您可以在运行应用程序时使用jvisualvm (jdk / bin)分析工具更好地对其进行分析。
I can comment but in terms of memory usage u can take a memory dump (heap dump) of running app by doing that: jmap -dump:format=b,file=cheap.bin <pid>
我可以发表评论,但是就内存使用而言,您可以通过执行以下操作来获取正在运行的应用程序的内存转储(堆转储): jmap -dump:format=b,file=cheap.bin <pid>
Then install MAT of course if you are using ECLIPSE open that file in eclipse and compare objects sizes. 如果使用ECLIPSE,则当然要安装MAT ,然后在eclipse中打开该文件并比较对象大小。 I used that to find out memory leaks in my web app with servlets and Tomcat server It is really useful 我用它来找出带有servlet和Tomcat服务器的Web应用程序中的内存泄漏,这真的很有用
But if you are not interested in that take look on that question get OS-level system information 但是,如果您对此不感兴趣,请查看该问题以获取操作系统级别的系统信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.