简体   繁体   中英

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.

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.

  1. Most efficient; storing in a long value: 8 bytes (further it is immutable when passed as param)

  2. 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)

  3. 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

  4. 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:

  • Easy to Use. Calendar makes accessing 'normal' dates difficult, due to the lack of simple methods. Joda-Time has straightforward field accessors such as getYear() or getDayOfWeek().
  • Easy to Extend. The JDK supports multiple calendar systems via subclasses of Calendar. This is clunky, and in practice it is very difficult to write another calendar system. Joda-Time supports multiple calendar systems via a pluggable system based on the Chronology class.
  • Comprehensive Feature Set. The library is intended to provide all the functionality that is required for date-time calculations. It already provides out-of-the-box features, such as support for oddball date formats, which are difficult to replicate with the JDK.
  • Up-to-date Time Zone calculations. The time zone implementation is based on the public tz database, which is updated several times a year. New Joda-Time releases incorporate all changes made to this database. Should the changes be needed earlier, manually updating the zone data is easy.
  • Calendar support. The library currently provides 8 calendar systems. More will be added in the future.
  • Easy interoperability. The library internally uses a millisecond instant which is identical to the JDK and similar to other common time representations. This makes interoperability easy, and Joda-Time comes with out-of-the-box JDK interoperability.
  • Better Performance Characteristics. Calendar has strange performance characteristics as it recalculates fields at unexpected moments. Joda-Time does only the minimal calculation for the field that is being accessed.
  • Good Test Coverage. Joda-Time has a comprehensive set of developer tests, providing assurance of the library's quality.
  • Complete Documentation. There is a full User Guide which provides an overview and covers common usage scenarios. The javadoc is extremely detailed and covers the rest of the API.
  • Maturity. The library has been under active development since 2002. Although it continues to be improved with the addition of new features and bug-fixes, it is a mature and reliable code base. A number of related projects are now available.
  • Open Source. Joda-Time is licenced under the business friendly Apache License Version 2.0.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM