views:

895

answers:

4

Hi all,

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

+10  A: 

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.

Jon Skeet
yeah, profile it first, so you don't waste time fixing what's not broken.
Don Branson
I'll second that. If this really is a bottleneck for your app, you are probably writing it in the wrong language.
Eric Petroelje
+3  A: 

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.

unforgiven3
you're right, optimization should come after correct implementation and profiling. I was just trying to think ahead. Though it still serves as a lesson in java theory.
jbu
+5  A: 

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.

erickson
so it sounds like array of primitives can be stored in contiguous memory but not an array of objects. is that correct?
jbu
Arrays are contiguous - but if you have an array such as Foo[] that means an array of Foo *references*, not Foo *objects*. Java doesn't have user-defined value types.
Jon Skeet
A: 

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.

KitsuneYMG
<pedantry>Objects aren't passed by references. References (and all other arguments too) are passed by value. There's a big difference, and it's worth being precise.</pedantry>
Jon Skeet