Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to improve application to avoid heap space issues

I have an application that works heavily with many custom objects that are created inside methods and never needed outside of them. The whole structure is (in my opinion) very good object oriented and uses Services, Utilities and a DI-Model.

Now, as I ran my first "large" tests, I quickly encountered OutOfMemoryExceptions. Now, I don't just want to increase the heap space and be done with it, as I can imagine that will not solve the problem but rather delay it until my application has grown more and encounter the same problem then.

I'm looking for some simple and easy to implement solutions, tips and snippets that help an application deal with garbage collection and heap spaces, especially when it comes to many loops that operate with object creation.

Something like "don't create objects in loops, create them before the loop and overwrite it within" and the sorts.

like image 804
F.P Avatar asked Mar 02 '12 13:03

F.P


2 Answers

Some points:

  • There is nothing fundamentally wrong with increasing heap space. Different applications tend to have different requirements.
  • Use profiler to see what really is happening. For example here you can find heap analyzer: MAT
  • When you find out that instances of certain class are responsible of 80% of heap consumption:
    • try to find commonly shared set of variables with same values. Those are candidates to be one object which can be shared by multiple objects.
    • Check especially are you storing some reference to relatively big object graph to the variable that lives much longer than your loops (local variables consume stack).
    • Let references drop out of scope as fast as possible.
    • If you use inner classes, check ones that are not static, because non-static inner class holds reference to the containing object.
like image 70
Mikko Maunu Avatar answered Sep 29 '22 02:09

Mikko Maunu


The most important piece of advice that I can give you is the same as with any performance issue:

Profile, improve, repeat

Use a profiler (e.g. VisualVM) to find where the largest amount of memory is consumed. Improve your code, first to remove any memory leaks and then to reduce memory consumption in general. Repeat this process until you are satisfied with the quality and performance of your code.

EDIT:

A few tricks of the trade:

  • Share objects instead of duplicating, when possible.

  • Beware of the Java collection classes (i.e. the various Collection<T> and Map<K,V> implementations). Depending on what you are storing and what the collection in use is, you can easily increase your memory consumption by an order of magnitude without expecting it.

  • While Java does not (normally) have memory leaks in the same sense as encountered in C, Java code often has an issue with objects that are kept alive past their expiration date.

    To avoid this, limit the scope of your references as much as possible or set them to null when you are done with that object. Note: don't over do it with the null-setting, especially in trivial methods that are expected to return soon.

    Most importantly: make sure you remove an object from any collections it might have been entered into when you are done with it. Not doing so is a good recipe for an OutOfMemoryError - and the most common cause of what people call a memory leak in the Java world.

like image 20
thkala Avatar answered Sep 29 '22 02:09

thkala