I need to store a large amount of dates (potentially large enough that the amount of heap space used is a concern so please, no lectures on premature optimization), and I'm wondering if it makes sense to use some sort of primitive representation instead of java.util.Date (or some other existing Date class). I know I could do some profiling to try it out, but does anyone know off-hand exactly how many bytes of memory a single Date object uses?
-
2Could you store the date as a long primitive and convert it to a Date when needed? – BacMan Jan 13 '11 at 15:48
7 Answers
My gut reaction was that the memory overhead for Date would be very small. Examining the source code it seems that the class only contains one instance field (a long called milliseconds). Which means the size of a date object is the size of a long plus the size of an instance of Object -- that is, very small.
I then found this code that creates thousands of objects to determine the size of the object. It says that the size of java.util.Date
is 32 bytes. Compare that with just storing a the date as a long (which is what it does internally) -- a long is 8 bytes, so you have to pay four fold for the convenience of having a date object.
However, the overhead of creating of objects isn't very high. So if you're really that worried about space then store the dates as longs and create a Date object as and when needed.

- 37,291
- 7
- 81
- 97
-
Thanks! I know objects are more bloated than primitives but I wasn't expecting a 4-fold difference. – Michael McGowan Jan 13 '11 at 16:06
-
It's because Date is just a wrapper object for the long. I had a quick look at the API, and everything that would make the Date object useful is deprecated, and has been replaced by Calendar. – Dunes Jan 13 '11 at 16:08
-
@Dunes, the down side of Calendar is it is far more expensive. I suggest you only use calendar as you need them. – Peter Lawrey Jan 13 '11 at 16:13
-
Bloat is a relative term. Java supports garbage collection of objects, which at a minimum means the object must have it's id stored and that id's current space in memory. The object also needs a reference to it's type. There's probably more than I'm considering at the moment, but such storage is only bloat if you don't want the features object provide. If you don't want those features, allocate an array of longs and be done with it. – Edwin Buck Jan 13 '11 at 16:18
-
@Peter Good tip about the Calendars. Something I was trying to express as well. Though perhaps, I didn't express myself very well. – Dunes Jan 13 '11 at 16:29
-
Along @Edwin's point, whether you use 8 bytes, 32 bytes or 1 kB, really doesn't matter in a modern computer. esp. if the object will be quickly recycled. It only really matters if you have allot of these objects. i.e. 100's MB. You can buy a 24 GB server for around £1,800. making 100 MB cost less than £10. – Peter Lawrey Jan 13 '11 at 16:51
-
3@Peter It's true that it only really matters if you have a lot of these objects, but I was quite explicit that I *do* have lots of these objects. In my application we've already encountered numerous instances where a developer used the "memory is cheap" philosophy that you described, only to have it come back to bite us. Also a customer might want to use our software without needing to buy a new computer (and they might have a 32-bit OS that limits their potential heap size). – Michael McGowan Jan 13 '11 at 17:07
-
@Michael, memory is cheap if you are willing to buy a new machine and your overheads are not high (in some organisations the overheads are staggeringly high) I was recently surprised to find you can buy an off the shelf server with 1 TB of memory for £53K. Having lots of memory is not a technical problem, but the most difficult ones rarely are. ;) – Peter Lawrey Jan 13 '11 at 17:17
-
If you want a collection for these long dates have a look at TLongArrayList and TLongHashSet. – Peter Lawrey Jan 13 '11 at 17:24
-
As has been suggested you may be able to encode the date/time so they fit in an int value. Either use seconds or milli since the start of the year etc. – Peter Lawrey Jan 13 '11 at 17:28
Use the primitive long ?
It is not an object, so less space, and dates can be expressed as a long value. Then convert back and forth between Date and long when you want to store the dates and use less memory.

- 5,242
- 7
- 39
- 57
-
Using a primitive long was the alternative I had in mind. However, I was envisioning writing a bunch of custom methods to do what Date already does instead of creating Date objects as needed as you suggest. – Michael McGowan Jan 13 '11 at 15:57
-
1Make sure you use 'long' and not 'Long' or you won't get the benefit you are looking for. A long is about 4x smaller than a Date. – Peter Lawrey Jan 13 '11 at 16:15
As answered here too:
Easiest way to answer this question is to look at the source code of java.util.Date
.
It has only 2 non-static fields (Java 1.7.0_55):
private transient long fastTime;
private transient BaseCalendar.Date cdate;
long
has a memory size of 8 bytes and cdate
is an object reference which has a size of 4 bytes. So a total of 12 bytes.
If cdate
would be instantiated, it could require additional bytes in the memory, but if you look at the constructors too, sometimes it won't even be touched, and in others it will be null
-ed at the end of the constructor, so the final result is also 12 bytes.
This is just for creating a Date
. If you call methods on the Date
(for example Date.toString()
), that will create and store an object into the cdate
field which will not be cleared. So if you call certain methods on the Date
, its memory usage will increase.
Note: Object references might be 64 bit long on 64-bit JVMs in which case memory usage would be 16 bytes.
Note #2: Also note that this is just the memory usage of the Date
object itself. Most likely you will store its reference somewhere, e.g. in an array or list or a field in some other class which will require additional 4 bytes (or maybe 8 bytes on 64 bit JVMs).
I tried a manual calculation based on the rules here: http://www.javamex.com/tutorials/memory/object_memory_usage.shtml and checking the source code of the Date object in Java 7 the memory usage.
Object overhead: 8 bytes => 8 bytes
+ 1 long fastTime: 8 bytes => 16 bytes
+ 1 reference cdate: 4 bytes => 20 bytes
Rounded up to nearest multiple of 8 => 24 bytes
Maybe I'm missing something in the calculation or the tools that were used in other answers that gave a result of 32 were including the references to the dates themselves in the calculation?

- 14,642
- 6
- 27
- 39
If it's literally date, rather than date & timestamp, you could even use an int:
20110113

- 6,391
- 3
- 33
- 49
java.util.Date object can be represented by a long value and a long value is 8 bytes -2^63 to (2^63)-1

- 14,361
- 2
- 45
- 50
-
I know a long is 8 bytes and *can* be used to represent a date, but I don't know if that's what java.util.Date does. Also the fact that an object is not primitive might mean it is larger even if backed by a long. – Michael McGowan Jan 13 '11 at 15:58
-
@Micheal, You are right, date object is probably larger than 8 bytes but it is not because it is using a different way to represent the date inside, it is because it has several other objects defined inside. See the implementation of the Date class. long is big enough to make sure that hold the exact time, not jsut in ms, it is even big enoguh to hold time in nanoseconds. – fmucar Jan 13 '11 at 16:05