What are the prons and cons between using "static Hashmap store object" and apache java cache system for web based enterprise apps? Which one is best for performance and reduce heap memory problem
ex:
Map store=ApplicationCtx.getApplicationParameterMap();
UserObj obj=store.get('user');
VS
UserObj obj = JCS.getInstance("user");
If you want the best of both worlds, you might consider using a synchronized LinkedHashMap which can be used as an LRU cache (a basic eviction policy) and is thread safe.
A HashMap is simpler and faster, it doesn't do very much and is not thread safe. (Which is why it is the fastest)
Most Caching systems are more sophisticated which means there will be a small overhead. e.g. they are thread safe (which I am sure you will need) and support eviction policies (which you also indicate you will need)
In short, the first one is fastest but probably won't do what you need. The second will help you manage how much memory you use.
Related
Use case: a single data structure (hashtable, array, etc) whose members are accessed frequently by multiple threads and modified infrequently by those same threads. How do I maintain performance while guaranteeing thread safety (ie, preventing dirty reads).
Java: Concurrent version of the data structure (concurrent hashmap, Vector, etc).
Python: No need if only threads accessing it, because of GIL. If it's multiple processes that will be reading and updating the data structure, then use threading.Lock. Force the each process's code to acquire the lock before and release the lock after accessing the data structure.
Does that sound reasonable? Will Java's concurrent data structure impose too much penalty to read speed? Is there higher level concurrency mechanism in python?
Instead of reasoning about performance, I highly recommend to measure it for your application. Don't risk thread problems for a performance improvement that you most probably won't ever notice.
So: write thread-safe code without any performance-tricks, use a decent profiler to find the percentage of time spent inside the data structure access, and then decide if that part is worth any improvement.
I bet there will be other bottlenecks, not the shared data structure.
If you like, come back to us with your code and the profiler results.
We are writing a test framework and we want to maintain a data structure for storing objects at suite level, objects vary from int to slf4j Logger. I am not clear as which data structure to use, which is more effective.
A HashMap is simpler and faster, is not thread safe. (that is why it is fastest)
Other Caching systems are more sophisticated which means there will be a small overhead. Also will be thread safe.
JCS support LRU and MRU, The LRU Memory Cache is an extremely fast, highly configurable memory cache. It uses a Least Recently Used algorithm to manage the number of items that can be stored in memory. The LRU Memory Cache uses its own LRU Map implementation that is significantly faster than both the commons LRUMap implementation and the LinkedHashMap that is provided with JDK1.4 up.
a good read here
Object creation is a bottleneck in my application.
I think that adding more threads for object creation makes the situation worse, because object creation is a CPU-bound task, right?
Then, how to improve performance?
Often the problem is not object creation itself, but repeated object creation and garbage generation. That causes two performance hits: creating all those objects and extra garbage collection stalls.
First, you should use profiling tools to verify that excessive object creation is the source of your performance problems. Assuming that you have verified that this is the problem, there are various things to look for and strategies to try. It all depends on how your code is written, so there's no one recommendation that will work. This list of Java performance guidelines from IBM is definitely worth applying. It identifies how to avoid many of the most common sins: don't create objects inside loops; use StringBuilder instead of a series of string concatenation expressions; use primitive types and avoid auto-boxing/unboxing where possible; cache frequently used objects; allocate collection classes with an explicit capacity instead of allowing them to grow; etc.
Another nice resource is Chapter 4 of the book Java Performance Tuning. (You can read it on-line here.)
If you search the web for excessive object creation java, you can find lots of other recommendations.
You can still get significant performance improvement by multi-threading CPU bound tasks when your app is running on a machine with multiple processors.
As #Pst says - are you sure it's the bottleneck? because these days it's not a common one.
But given that. One thing you could try is avoiding creation by caching and reusing instances. But that totally depends on what your program does.
Java uses a TLAB (Thread Local Allocation Buffer) for small to medium sizes objects. This means each thread can allocate objects concurrently. i.e. you don't get a slow down for using multiple threads.
In general, more CPUs improve CPU-bound problems. Its IO bound tasks where one cpu can use all the available bandwidth, like disk access, which are no faster when you use multiple CPUs.
The simplest way to reduce the cost of Object Creation is to create/discard less objects. There is a common assumption that object creation is unavoidable, but the last 2.5 years I have worked on applications which GC less than once per day, even under production load.
Most application don't work this way because they don't need to. However, if you have a need to minimise object creation you can.
I am developing a Java desktop application where I have many caches, such as object pools, cached JPanels ...etc.
Example:
When a user switches from one Panel to another, I don't destroy the previous one in case the user switches back.
But, The application memory consumption might get high while the system is in desperate need of these memory resources that I am consuming not so justifiably...
In an iOS application, I would release these in "applicationDidReceiveMemoryWarning" method. But in Java... ?
So, When is it a good time to release cached objects in Java?
Caching often isn't a good idea in Java - creating new objects is usually much cheaper than you think, and often results in better performance than keeping objects cached "just in case". Having a lot of long-lived objects around is bad for GC performance and also can put considerable pressure on processor caches.
JPanels for example - are sufficiently lightweight that it's fine to create a completely new one whenever you need it.
If I were you, I'd cache as little as possible, and only do so when you've proved a substantial performance benefit from doing so.
Even if you do need to cache, consider using a cache that uses Soft References - this way the JVM will be able to clear items from the cache automatically if it needs to free up memory. This is simpler and safer than trying to roll your own caching strategy. You could use an existing Soft Reference cache implementation like Guava's CacheBuilder (thanks AlistairIsrael!).
I'm looking to implement a simple cache without doing too much work (naturally). It seems to me that one of the standard Java collections ought to suffice, with a little extra work. Specifically, I'm storing responses from a server, and the keys can either be the request URL string or a hash code generated from the URL.
I originally thought I'd be able to use a WeakHashMap, but it looks like that method forces me to manage which objects I want to keep around, and any objects I don't manage with strong references are immediately swept away. Should I try out a ConcurrentHashMap of SoftReference values instead? Or will those be cleaned up pretty aggressively too?
I'm now looking at the LinkedHashMap class. With some modifications it looks promising for an MRU cache. Any other suggestions?
Whichever collection I use, should I attempt to manually prune the LRU values, or can I trust the VM to bias against reclaiming recently accessed objects?
FYI, I'm developing on Android so I'd prefer not to import any third-party libraries. I'm dealing with a very small heap (16 to 24 MB) so the VM is probably pretty eager to reclaim resources. I assume the GC will be aggressive.
If you use SoftReference-based keys, the VM will bias (strongly) against recently accessed objects. However it would be quite difficult to determine the caching semantics - the only guarantee that a SoftReference gives you (over a WeakReference) is that it will be cleared before an OutOfMemoryError is thrown. It would be perfectly legal for a JVM implementation to treat them identically to WeakReferences, at which point you might end up with a cache that doesn't cache anything.
I don't know how things work on Android, but with Sun's recent JVMs one can tweak the SoftReference behaviour with the -XX:SoftRefLRUPolicyMSPerMB command-line option, which determines the number of milliseconds that a softly-reachable object will be retained for, per MB of free memory in the heap. As you can see, this is going to be exceptionally difficult to get any predictable lifespan behaviour out of, with the added pain that this setting is global for all soft references in the VM and can't be tweaked separately for individual classes' use of SoftReferences (chances are each use will want different parameters).
The simplest way to make an LRU cache is by extending LinkedHashMap as described here. Since you need thread-safety, the simplest way to extend this initially is to just use Collections.synchronizedMap on an instance of this custom class to ensure safe concurrent behaviour.
Beware premature optimisation - unless you need very high throughput, the theoretically suboptimal overhead of the coarse synchronization is not likely to be an issue. And the good news - if profiling shows that you are performing too slowly due to heavy lock contention, you'll have enough information available about the runtime use of your cache that you'll be able to come up with a suitable lockless alternative (probably based on ConcurrentHashMap with some manual LRU treatment) rather than having to guess at its load profile.
LinkedHashMap is easy to use for cache. This creates an MRU cache of size 10.
private LinkedHashMap<File, ImageIcon> cache = new LinkedHashMap<File, ImageIcon>(10, 0.7f, true) {
#Override
protected boolean removeEldestEntry(Map.Entry<File, ImageIcon> eldest) {
return size() > 10;
}
};
I guess you can make a class with synchronized delegates to this LinkedHashMap. Forgive me if my understanding of synchronization is wrong.
www.javolution.org has some interestig features - synchronized fast collections.
In your case it worth a try as it offers also some nifty enhancements for small devices as Android ones.
For synchronization, the Collections framework provides a synchronized map:
Map<V,T> myMap = Collections.synchronizedMap(new HashMap<V, T>());
You could then wrap this, or handle the LRU logic in a cache object.
I like Apache Commons Collections LRUMap