Search |
||
Persistence Caching Part IIPosted by jhook on January 5, 2007 at 10:07 PM PST
Often when you are looking at caching 'requirements', you have a couple things to think about:
No where do requirements base themselves on 'do not store more than 200 widgets at once in memory'. So why do these caching implementations work that way? Granted, there's opportunity to roll over to the file systems in these cache frameworks, but really-- if I wanted to guarantee persistence like that, I'd just store it to the disk in the first place or in the DB. Seriously. Anything I'd throw into a 'cache' would be just extra. Hibernate has strongly referenced 1st level caching, which makes complete sense for transactions, second level caches are just there to help with performance. So what do we do? Lets take OSCache as an example. What I really want to do is specify a time to live (requirement 1) and either softly or weakly reference the data to allow the JVM to naturally optimize memory use. This means I can store an unbounded set of widgets in memory (None of this LRU/FIFO/LFU stuff), but still enforce that if the widget sticks around long enough, to put some restriction on how long until we allow it to be dirty again (forcing a re-fetch). If you are dealing with bounded sets-- such as a couple of known articles or highlighted data, then fine, use a cache capacity/LRU-- but for unbounded sets where caching is purely there to enhance performance of the overall system-- just weakly or softly reference the data. It is a cache after all. This becomes especially important in web applications where traditionally, we store data per session to optimize the user experience. But-- what if 80% of that data is required by another user? Could we push the cache to a global scope, out of the session and weakly reference it, such that all users share the same memory? I guess you could still store reference in your session, but globally weakly referencing the data would be an 'automatic' way of sharing common session data that's purely there for cache optimization. The other thing would be to softly reference everything. In this case, you would just be able to store whatever you can globally, knowing that it will get cleaned up as the VM needs to allocate memory elsewhere. Still retaining the time to live policy here is important to prevent objects from sticking around for days at a time when you want to 'update' the cached instance after 20 or 30 minutes. Another performance tweak to this with soft references, if the overhead of using soft references becomes too much, you can decide to 'chunk' your caches into segments where a whole series of caches can be softly referenceable, instead of per object.
Lookups would then be Key to Reference, Reference to Cache, Key to Instance. Anyways, again, let me know your thoughts-- I've committed to using an existing cache implementation, but all of the settings of these popular libraries just seems disjoint to actual application use cases. Update from Bob's CommentsI implemented a straight What I wanted to see is how accurate the use of
So what do the numbers mean? ThreadCaching adds some overhead, to time/memory, but when the timer is able to clean up references before the GC, then we do get a better set of recent objects sticking around in the cache (good). For large objects, they get gc'ed before the timer can get to them, rendering them useless. »
Related Topics >>
Java Enterprise Comments
Comments are listed in date ascending order (oldest first)
|
||
|
|