2

I am currently developing an application that need to be very fast executing about every 20ms (yeah I know, should not have taken Java in the first place). I worked a lot optimizing the code so it would not be too computation greedy. However, as I have seen I may have not put enough effort in GUI and memory optimization. My application can run at the speed I want but after 1-2 minutes it drastically slowdown suggesting a memory problem.

I did run the profiler under NetBeans and found out that most of the memory was taken by the javax.swing.text.GapContent$MarkData

And searched on google, I saw mostly nothing understandable helping me with that problem. So is there anyone that could help me? My first guess would be that the garbage collector doesn't run long enough to erase unused object...but I don't have more clue than that.

enter image description here

Zonata
  • 471
  • 2
  • 6
  • 20
  • 1
    In order to get some help, you will have to add some code.. –  May 22 '13 at 05:37
  • Well, there is literaly many thousands of lines of code. I wanted to get and idea where to start first. – Zonata May 22 '13 at 05:38
  • 1
    Swing is infamous for all these memory buildups (I won't call it memory leak). Its better to reuse Swing elements rather than instantiating them newly every time. – Pradeep Pati May 22 '13 at 05:40
  • @Zonata any code related to "GapContent" or text manipulation –  May 22 '13 at 05:44
  • @RC What is GapContent exactly, the javadoc do not say much. Could it be a component that do not get emptied and thus build up? – Zonata May 22 '13 at 05:48
  • I runned manually the GC an nothing happened, confirming it is not a memory leak. – Zonata May 22 '13 at 05:51
  • 3
    +1 for [profiling](http://stackoverflow.com/q/2064427/230513); now use `Profile > Profile Project > CPU` to find and target the hot spot(s). – trashgod May 22 '13 at 09:35
  • 1
    @trashgod Darn, can't believe that, the slowdown was due to a fonction that closed and opened a connection with the database each iteration (connected over Wi-Fi). Happy that such tools exist nowaday... pretty sure I would never have found the problem if not. – Zonata May 24 '13 at 00:08
  • @Zonata: Glad you were able to focus on the problem; I've elaborated in an answer below. – trashgod May 24 '13 at 01:09

3 Answers3

3

You are right to employ profiling; now use Profile > Profile Project > CPU to find and target the hot spot(s).

The slowdown was due to a function that closed and opened a connection with the database each iteration.

Consider using SwingWorker to query the database in the background and process() results on the event dispatch thread, as shown in this related example.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • 2
    +1 For two great suggestions. Hitting database in background is correct and will make the app feel faster but it won't actually improve throughput. Publish/Process also makes it feel faster adn it does allow some concurrency: one thread can be doing ui work on some of the results while the rest are being found/generated. But the biggest improvement will come from solving the underlying problem - Write batch operations so that the db connection isn't opened and closed on each iteration. – Ryan May 24 '13 at 18:53
2

What you are calling a "Memory build up" is only 600Kb. If this 600Kb is problematic I question your choice of Java and Swing.

I have an application that sometimes generates hundreds of megabytes of log messages. I'm guessing your GUI application is somewhat similar. The app probably has a JTextPane that displays a log. As the app runs it adds messages to the JTextPane.
The Document implementation used by JTextPane is a PlainDocument.
Even though you probably always insert new log messages at either only the top or only the bottom, the PlainDocument implementation is general-purpose. It supports modification anywhere in the document by putting a gap in the underlying stream of text and then putting the changes into the gap. As the app inserts new messages into the Document it creates lots and lots of Gaps.
The actual text to display has to exist somewhere. There is probably a better way to implement a huge text pane, but the default JTextPane will look, to the profiler, like a memory leak. If you have 600kb of log messages, its going to take at least 600kb of memory somewhere.

Ryan
  • 2,061
  • 17
  • 28
  • 1
    +1 Thank you for having pointed that to me (I was blinded by my certainty). Maybe the drop in performance of my app is due to something else then. I will try to make the app run without the GUI to see if the problem still exists and look toward the potential components that might cause this problem. – Zonata May 23 '13 at 17:07
1

You should know that the Java Console uses a PlainDocument with GapContent$MarkData and just having the console open with lots of data in it will cause this "memory leak" to appear. Clear the console to see the number of MarkData drop back to acceptable levels.

mogsie
  • 4,021
  • 26
  • 26
  • +1 Not really related to the problem since the problem wasn't a memory leak finally, but interesting information. – Zonata Apr 17 '15 at 14:40