0

I have a Java RESTful service that creates a new JSON object every 10 seconds and pushes it to a URL to be consumed by AngularJS.

The problem is that I don't think the old JSON object is being freed up in memory. When I run task manager, I see that the java process increases in size approximately every 10 seconds. I don't want this to happen when it's running indefinitely.

How can I fix this?

Here is the class:

@Path("/")
public class MQDepthJson extends TimerTask {

    public MQDepthJson() {

    }

    private int count = 0;
    private static final int ARRAY_SIZE = 11;
    MQDepth[] mqDepths = new MQDepth[ARRAY_SIZE];
    String[] c = {"c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11"};
    Timer timer;    

    public String getMQDepthJson() {            

        Gson gson = new Gson();

        while(count < 11) {
            MQDepth mq = new MQDepth();
            int currentDepth = mq.calculateCurrentDepth();
            mq.setCurrentDepth(currentDepth, c[count]); 
            mqDepths[count] = mq;
            count++;
        }       
        count = 0;              

        return gson.toJson(mqDepths);
    }

    @GET
    @Path("/mqDepthJson")
    @Produces("application/json")
    public String runTask() {

        while(true) {
            Timer timer = new Timer();
            timer.schedule(new MQDepthJson(), 10000);

            return getMQDepthJson();
        }
    }


    @Override
    public void run() {

        getMQDepthJson();       
    }
}
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
UltraSonja
  • 881
  • 1
  • 20
  • 33
  • This doesn't seem like a memory leak. – Luiggi Mendoza Oct 12 '15 at 14:23
  • 1
    This sounds pretty normal unless you're actually getting an `OutOfMemoryError` (and even then doesn't necessarily mean a memory leak). Objects will stick around until they get garbage collected, which could be quite a while. – JonK Oct 12 '15 at 14:25
  • @LuiggiMendoza Is it just a problem with not freeing up memory? I'm not sure what's going on to be honest. – UltraSonja Oct 12 '15 at 14:25
  • If you're executing your JVM using `-server` parameter, then you should read [this](http://stackoverflow.com/q/198577/1065197). – Luiggi Mendoza Oct 12 '15 at 14:27
  • @JonK So this isn't a problem then? – UltraSonja Oct 12 '15 at 14:27
  • It *probably* isn't, but if you're concerned about it, then attach a profiler and keep an eye on it for a while. You should see a zig-zag shaped memory profile as the heap usage builds and builds, then a near vertical drop down to a low base-level each time the Garbage Collector runs, followed by another slow increase and another near vertical drop, and so on. – JonK Oct 12 '15 at 14:29
  • @UltraSonja The only way you can be somewhat sure is to run it for many iterations (reduce the timer interval?) and see if it gets garbage collected. – Phylogenesis Oct 12 '15 at 14:30
  • What version of the JRE are you using? Have you defined any GC parameters? Its possible you may be using by default the Parallel GC on JRE 1.6. GC may only kick in if you are approaching the memory limits allocated to your JVM. – Damien O'Reilly Oct 12 '15 at 14:38
  • Thank you for all of the suggestions. I ran the JVM with the `-server` option, and I could see when the GC ran... which is good. Although the memory allocated for the JVM with the `-server` option is 2x as much than without it. – UltraSonja Oct 12 '15 at 14:39
  • @DamienO'Reilly I'm running my application on the JBoss 7.4 server with Java 7. – UltraSonja Oct 12 '15 at 14:46
  • @UltraSonja I think you should reduce the interval (e.g. your 10 secs down to 1 sec) and memory allocated to the VM for test purposes, and observe what happens. I think you will see that GC will kick in as you approach the max memory limited allocated to your VM. The VM will most likely pause while this is ongoing. That may be something you need to worry about later if response times are critical for you. – Damien O'Reilly Oct 12 '15 at 14:49

2 Answers2

0

There are no memory leaks in Java. You bother with creating objects and not with deleting them. When an object goes out of scope there are no more valid references to it. At some point in the future the garbage collector will free the memory.

You may have in Java unintentional object retention. There is the potential for that in your code because you are using arrays instead of ArrayList. In your code if you no longer need an MQDepth in mqDepths array you must set the value in that position of the array to null. Like this

mqDepths[3] = null;

Using an ArrayList would be highly recommended what you are doing with arrays.

Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
0

Garbage collector will automatically release later on for the objects, whose reference variables are not found. If you want explicitly to do garbage collection, then use System.gc()

munish
  • 453
  • 6
  • 22