I am trying to implement a cache-like collection of objects. The purpose is to have fast access to these objects through locality in memory since I'll likely be reading multiple objects at a time. I currently just store objects in a java collections object like vector or deque. But I do not believe this makes use of contiguous memory.
I know this can be done in C, but can it be done in Java? These objects may be of varying lengths (since they may contain strings). Is there a way to allocate contiguous memory through Java? Is there a Java collections object that would?
Please let me know.
Thanks, jbu
No, you can't guarantee this locality of reference.
By allocating a byte array, or using a mapped byte buffer from the
nio
packages, you could get a chunk of contiguous memory, from which you can decode the data you want (effectively deserializing the objects of interest from this chunk of memory). However, if you repeatedly access the same objects, the deserialization overhead would likely defeat the purpose.I suggest using a HashMap (no threaded) or Hashtable (threaded) for your cache. Both store an object into an array in the sun jvm. Since all objects in java are passed by reference, this should be represented as an array of pointers in c. My bet is that you are performing premature optimization.
If you absolutely must have this, you have two options:
1) Use JNI and write it in c. 2) Get a BIG byte buffer and use ObjectOutputStream to write objects to it. This will probable be VERY SLOW compared to using a hash table.
Have you written this code yet in Java? And if so, have you profiled it? I would argue that you probably don't need to worry about the objects being in contiguous memory - the JVM is better at memory management than you are in a garbage collected environment.
If you're really concerned about performance, maybe Java isn't the right tool for the job, but my gut instinct is to tell you that you're worrying about optimization too early, and that a Java version of your code, working with non-contiguous memory, will probably suit your needs.
You can't force it. If you allocate all the objects in quick succession they're likely to be contiguous - but if you're storing them in a collection, there's no guarantee that the collection will be local to the actual values. (The collection will have references to the objects, rather than containing the objects themselves.)
In addition, GC compaction will move values around in memory.
Have you actually profiled your app and found this is a bottleneck? In most cases I'd expect other optimisations could help you in a more reliable way.