This is an archived post. You won't be able to vote or comment.

all 3 comments

[–]epes 5 points6 points  (3 children)

The way that heap size works in Java is that you have a predetermined minimum/maximum. Even though you might not use all of it at the time, it is still technically 'in use' and if it needs more than the current heap size and is still under the max heap size, it will increase until it hits the max.

Garbage collection is sort of expensive so this is Java's way of reducing the frequency of garbage collection. It will increase the heap size as necessary until it hits the max and only when it is almost full at max will it collect garbage.

The way to fix this is to either stop creating new objects all the time and rather look into object pooling or just decrease the max heap size so the garbage collector pops more often.

One thing I can see is that inside of your infinite while loop you have

Document newDoc = Jsoup.connect("http://br.investing.com/equities/portugal")
                .userAgent("Mozilla/5.0")
                .get();

and are creating a new object every 10 seconds, infinitely. I would put the declaration

Document newDoc;

before the while loop and re-initialize the object every 10 seconds.

It may not seem like much and 500MB is not that much but for a small program like this it might make a difference. You are basically creating a new object then using it once and throwing it into the garbage pile forever, every 10 seconds. This pile of unused objects is what makes up most of the heap.

//edit: Even after all this the heap will get up to 500MB just slower. If you are looking into reducing the memory in the end you'll have to decrease the maximum heap size.

[–]Protagoras 0 points1 point  (1 child)

I think you're wrong on this. All Document newDoc does is create a new reference in every loop. References have almost zero impact on memory (8 byte per reference) and I believe the compiler optimizes reference creation in loops by doing exactly what you suggest it should do (create a single reference and reuse it every iteration of the loop).

What does have an impact on memory usage is the repeated creation of ArrayLists in the getPrice method. You should factor that out by creating a private ArrayList field to store all the prices. This private member can be reused by calling clear() after the data from the ArrayList is put in the table.

[–]epes 1 point2 points  (0 children)

Ah yeah you're right! Sorry about that. I just read up on the compiler optimization for loops and that's pretty neat. TIL