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.
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.
Or you can use 3rd party libraries such as java.sizeOf which will do this for you.
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. (I think this is default on Java 8) so we can ignore it.
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.
Datetime:
private long iMillis;
private Chronology iChronology;
Which is also long
+ object ref to other object that takes up memory.
Using 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):
javaDate = 24
localDate = 24
dateTime = 16928
As you can see jodatime takes up a lot of memory with all of its supporting classes. 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. 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.
Most efficient; storing in a long value: 8 bytes (further it is immutable when passed as param)
Java.util.Date
VM 64 bit: 12 for the object +8 for long value + 4 for ref to BaseCal.Date = 24 bytes
Sun VM 32 bit: 8 + 8 + 4 = 20 + 4 padding = 24 bytes
(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)
LocalDate
VM 64 bit: 12 + 4 + 2 + 2 = 20 +4 padding = 24 bytes
VM 32 bit: 8 + 4 + 2 + 2 = 16 bytes;
On android Dalvik: 12 + 4 + 4 + 4 = 24 bytes
joda DateTime
VM 64 bit: 12 + 8 + 4 for the reference to Chronology: = 24 bytes
VM 32 bit: 8 + 8 + 4 for the reference to Chronology + 4 padding = 24 bytes
How to measure such things probably? On Sun VM you can use MAT which uses a special featuire of the 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.
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.
Fields
A reference field needs 4 bytes. int: 4 bytes,
long 8,
short 2 (or 4 on Dalvik),
boolean 1 byte (Sun) , 4 bytes 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
According to joda-time, they offer the best way to work with dates:
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. The JDK classes Date and Calendar are very badly designed, have had numerous bugs and have odd performance effects. Here are some of our reasons for developing and using 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.
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>
Then install MAT of course if you are using ECLIPSE open that file in eclipse and compare objects sizes. I used that to find out memory leaks in my web app with servlets and Tomcat server It is really useful
But if you are not interested in that take look on that question get OS-level system information
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.