Java Forum / General / November 2007
REAL SSCCE of my graphical interface with memory leaks
Sal - 30 Oct 2007 18:19 GMT Hi All! I've some problems with a java program and memory leaks. I Export the classes in a jar file (with eclipse) and i run it with: java -jar app.jar
If i see the memory occupation of the program (CTRL+ALT+CANC java.exe application) i can see that the memory start from 14.600 KB and then grows up...
Why it appends?
Best Regards
Sal
<MAIN CLASS> package inter;
public class Principale {
public static void main(String[] args) {
try { Interfaccia2 app = new Interfaccia2(); } catch (NullPointerException e) {} } } </MAIN CLASS>
<INTERFACE CLASS> package inter;
import javax.swing.*; import java.util.*; import java.awt.*; import java.awt.event.*;
public class Interfaccia2 extends JFrame { JFrame f; JLabel timeField; int day = 0; int mese = 0; int anno = 0; int h = 0; int m = 0; int s = 0; Font fontlabel = new Font( "Verdana",Font.PLAIN,14); Dimension screenSize =Toolkit.getDefaultToolkit().getScreenSize(); public Interfaccia2() { timeField = new JLabel(""); javax.swing.Timer t = new javax.swing.Timer(1000, new ActionListener() { public void actionPerformed(ActionEvent e) { Calendar now = Calendar.getInstance(); day = now.get(Calendar.DAY_OF_MONTH); mese = now.get(Calendar.MONTH)+1; anno = now.get(Calendar.YEAR); h = now.get(Calendar.HOUR_OF_DAY); m = now.get(Calendar.MINUTE); s = now.get(Calendar.SECOND); timeField.setText("Data: "+ day + "-" + mese + "-" + anno + " Ore: " + h + ":" + m + ":" + s); } }); t.start(); // Start the timer timeField.setFont(fontlabel); JPanel Panel_principale = new JPanel(); Panel_principale.setPreferredSize (new Dimension (screenSize.width-10, screenSize.height-65)); Panel_principale.add (timeField); f = new JFrame ("TK Data"); f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); f.getContentPane().add (Panel_principale); f.pack(); f.setVisible (true); f.repaint(); } } </INTERFACE CLASS>
Mark Space - 30 Oct 2007 19:29 GMT > Dimension screenSize =Toolkit.getDefaultToolkit().getScreenSize(); The whole screen? Please don't do this. I changed it to:
// Dimension screenSize = //Toolkit.getDefaultToolkit().getScreenSize(); Dimension screenSize = new Dimension( 300, 300 );
> timeField.setText("Data: "+ day + "-" + mese + "-" + anno + " > Ore: " + h + ":" + m + ":" + s); The String here is broken, doesn't compile. I fixed it, but please watch this when you are posting code.
> If i see the memory occupation of the program (CTRL+ALT+CANC > java.exe application) i can see that the memory start from 14.600 KB > and then grows up... > > Why it appends? Mine grows up to 60MB up from 55MB, then goes back down to 54MB and starts growing again. This is normal for the JVM garbage collection. Are you sure you have a leak?
Also: public void actionPerformed(ActionEvent e) { Calendar now = Calendar.getInstance(); day = now.get(Calendar.DAY_OF_MONTH); mese = now.get(Calendar.MONTH) + 1; anno = now.get(Calendar.YEAR); h = now.get(Calendar.HOUR_OF_DAY); m = now.get(Calendar.MINUTE); s = now.get(Calendar.SECOND); timeField.setText("Data: " + day + "-" + mese + "-" + anno + "Ore: " + h + ":" + m + ":" + s); }
This strikes me as a really good way to have a serious problem. You're updating a JComponent ("timeField") on a thread that is not the AWT event thread. I think you should dump this whole method into an invokeLater() method.
Roedy Green - 30 Oct 2007 23:06 GMT On Tue, 30 Oct 2007 18:29:20 GMT, Mark Space <markspace@sbc.global.net> wrote, quoted or indirectly quoted someone who said :
>This strikes me as a really good way to have a serious problem. You're >updating a JComponent ("timeField") on a thread that is not the AWT >event thread. I think you should dump this whole method into an >invokeLater() method. He is ok. That is unnecessary because he used a Swing Timer not an ordinary Timer.
quoting from the docs "Although all Timers perform their waiting using a single, shared thread (created by the first Timer object that executes), the action event handlers for Timers execute on another thread -- the event-dispatching thread. This means that the action handlers for Timers can safely perform operations on Swing components. However, it also means that the handlers must execute quickly to keep the GUI responsive."
see http://mindprod.com/jgloss/timer.html
 Signature Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Mark Space - 30 Oct 2007 23:18 GMT > He is ok. That is unnecessary because he used a Swing Timer not an > ordinary Timer. Cool! I didn' know about Swing timers, thanks for the info.
Sal - 31 Oct 2007 00:17 GMT first of all thanks to all!
>Mine grows up to 60MB up from 55MB, then goes back down to 54MB and >starts growing again. This is normal for the JVM garbage collection. >Are you sure you have a leak? This is a program that run for 24h and after some days i have this problem of memory!
... and what about the occupation memory of the others? Have you seen it? I use WinXP and you?
Sal
Lew - 31 Oct 2007 00:42 GMT > This is a program that run for 24h and after some days i [sic] have this > problem of memory! What is the actual problem? In other words, what harm are you seeing?
> .... and what about the occupation memory of the others? > Have you seen it? > I use WinXP and you? Are you certain that you have a problem? What evidence besides seeing a number in the Task Manager do you have that there is a problem?
 Signature Lew
Sal - 31 Oct 2007 09:03 GMT > Are you certain that you have a problem? What evidence besides seeing a > number in the Task Manager do you have that there is a problem? > > -- > Lew Yes I'm sure that I've a memory leak, after some day running this program the memory grows up to 250Mb, i try to resolve it with this command: java -Xms32m -Xmx512m -jar TD3-1.jar
but it isn't sufficient :(
Thanks
Sal
Patricia Shanahan - 31 Oct 2007 11:59 GMT >> Are you certain that you have a problem? What evidence besides seeing a >> number in the Task Manager do you have that there is a problem? [quoted text clipped - 6 lines] > command: > java -Xms32m -Xmx512m -jar TD3-1.jar I'm confused. You are complaining that the JVM is using 250 MB, but you try to cure the problem by telling it that it is OK to use up to 512 MB for its heap?
Have you tested setting the -Xmx parameter to amount of heap space you think is reasonable for you job? Did you get a Java OutOfMemoryError?
Patricia
Lew - 31 Oct 2007 13:43 GMT >>> Are you certain that you have a problem? What evidence besides seeing a >>> number in the Task Manager do you have that there is a problem? [quoted text clipped - 3 lines] >> command: >> java -Xms32m -Xmx512m -jar TD3-1.jar Again, are you checking the memory with any tool other than Task Manager?
The memory allocated will often grow to the maximum allowed even without a memory leak. The presence of a large memory allocation is /not/ proof, or even evidence, that you have a memory leak.
That's important enough to repeat: you have /not/ shown any evidence, much less proof, to us that you actually have a memory leak.
What proof do you have that there is a memory leak?
 Signature Lew
Mark Space - 31 Oct 2007 04:09 GMT > first of all thanks to all! > [quoted text clipped - 8 lines] > Have you seen it? > I use WinXP and you? I'm using Windows Vista ultimate and Java 1.6.something. I can't, or won't, run you program for several days. I did let it run for several hours in the morning as I did other things. I saw no evidence of a leak.
I used NetBeans and the profiler that is available for it. Sang Shin has posted an excellent resource on his website on how to use the NetBeans profiler:
http://www.javapassion.com/handsonlabs/5116_nbprofilermemory.zip
In short, I saw no Generations number above 8.
Roedy Green - 30 Oct 2007 20:04 GMT >public class Principale { You could have easily made this one class. Just move the main method to intefaccia2. The fewer the classes the easier SSCCEs are to deal with.
There is a stylistic problem with your code. Your constructor is full of code nothing to do with constructing the Frame object. Even if you called such code from the constructor, application logic sort of code belongs in its own method.
The following code is traditionally never put in a constructor. f.pack(); f.setVisible (true); f.repaint(); /* not necessary */ You are supposed to do it in the code that calls new. I am not sure if this is just considered good style, or if something terrible happens if you do it your way. Consistent style is sufficient reason for me to avoid doing what you did.
I consider it dangerous to set up a timer inside an partially constructed frame. You want to wait until the frame is realised. This timer-starting code then belongs in addNotify.
See http://mindprod.com/jgloss/addnotify.html
 Signature Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Lew - 31 Oct 2007 00:44 GMT > The following code is traditionally never put in a constructor. > f.pack(); [quoted text clipped - 4 lines] > terrible happens if you do it your way. Consistent style is > sufficient reason for me to avoid doing what you did. It is actually dangerous, not just stylistically. All that Swing stuff should happen on the EDT, and you're not supposed to let thready things happen from the constructor.
In general, there can be severe bugs from putting non-construction logic in a constructor, especially where multi-threading is involved.
 Signature Lew
Sal - 31 Oct 2007 09:04 GMT > It is actually dangerous, not just stylistically. All that Swing stuff should > happen on the EDT, and you're not supposed to let thready things happen from [quoted text clipped - 5 lines] > -- > Lew Please, can you post an example of correct Swing programming? I'm not sure to understand the problem...
Thanks
Sal
Lew - 31 Oct 2007 13:44 GMT > Please, can you post an example of correct Swing programming? > I'm not sure to understand the problem... Sure: <http://java.sun.com/docs/books/tutorial/ui/index.html>
There ya go.
 Signature Lew
RedGrittyBrick - 31 Oct 2007 16:11 GMT >> Please, can you post an example of correct Swing programming? >> I'm not sure to understand the problem... [quoted text clipped - 3 lines] > > There ya go. I too am interested in Lew's rules of thumb: * All that Swing stuff should happen on the EDT. * Don't let thready things happen from the constructor. * Don't put non-construction logic in a constructor.
The following article might address some of Lew's points ... http://weblogs.java.net/blog/zixle/archive/2006/01/architecting_ap_1.html There's an earlier article that should really be read first.
which I reached from http://weblogs.java.net/mt/search?IncludeBlogs=234&search=passwordstore
which I reached from http://java.sun.com/docs/books/tutorial/ui/overview/demo.html
which I reached from http://java.sun.com/docs/books/tutorial/reallybigindex.html
Roedy Green - 30 Oct 2007 20:08 GMT Calendar now = Calendar.getInstance(); day = now.get(Calendar.DAY_OF_MONTH); mese = now.get(Calendar.MONTH)+1; anno = now.get(Calendar.YEAR); h = now.get(Calendar.HOUR_OF_DAY); m = now.get(Calendar.MINUTE); s = now.get(Calendar.SECOND); timeField.setText("Data: "+ day + "-" + mese + "-" + anno + "Ore: " + h + ":" + m + ":" + s);
This chunk of code is more slickly handled with a SimpleDateFormat. See http://mindprod.com/jgloss/calendar.html#PRECISE or with locale-dependence with DateFormat df = DateFormat.getDateInstance();
 Signature Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Roedy Green - 30 Oct 2007 20:48 GMT On Tue, 30 Oct 2007 19:08:08 GMT, Roedy Green <see_website@mindprod.com.invalid> wrote, quoted or indirectly quoted someone who said :
>This chunk of code is more slickly handled with a SimpleDateFormat. >See http://mindprod.com/jgloss/calendar.html#PRECISE >or with locale-dependence with DateFormat df = >DateFormat.getDateInstance(); The idea is to trim the code to the bone and still have it demonstrate the problem. You can replace this with setText( "Dummy" ); and see if it still fails.
 Signature Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Andrew Thompson - 31 Oct 2007 13:10 GMT >Hi All! G'day!
I ran 'your'* code for 8 hours on Win XP Pro using Java 1.6.0_02**. Besides that, I also ran jconsole (part of the 1.6 SDK, not sure of earlier versions).
Here is screenshots of the results. <http://www.physci.org/test/gc/>
* You code was horrible. Besides the wrapped long line that broke compilation, and the fact the main could be included within the one public class, there were a number of other things about the code I simply 'could not abide'. I changed those aspects of the code, but I believe the version I used was substantively the same as yours, and will *demonstrate the same behaviour on your testing PC.*
The code I used is linked from the page.
*Please run it and confirm the same behaviour you reported as a 'memory leak'.*
OTOH, given you obviously put a lot of effort into that example, and barring the single broken line, it was an SSCCE (or a close facsimile thereof***), so I thought it deserved a little more attenetion.
** Yes yes, I know.. _03 is the only safe version, I am evil for using _02 blah-de-blah..
*** Given it failed to satisfy the 'E' in that it was not an example of a memory leak.
<bottom-line> I agree with pretty much every comment made by each person who has replied to this thread. I think you are failing to understand the nature of Java GC (and just how 'lazy' it can be).
There is no 'memory leak' in the code shown.
I am just hoping these screenshots can convince you that your fears are unfounded.
OTOH, if your app. actually hits OutOfMemoryErrors, we need to look more closely at what it is doing, and (if my addled memory serves me well) what is happening with any Image's and ImageIcon's.. </bottom-line>
<sscce> import java.awt.Font;
import java.awt.event.ActionListener; import java.awt.event.ActionEvent;
import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.Timer; import javax.swing.SwingUtilities;
import java.util.Calendar;
public class Interfaccia2 extends JFrame { /** Used to update the timeField label. */ Timer timer; /** Original Timer was set for a 1000 ms delay. The delay used here, in ms, is.. */ int delay = 10;
public Interfaccia2() { super("TK Data"); setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
final JLabel timeField = new JLabel(""); timeField.setFont( new Font("Verdana",Font.PLAIN,14)); timer = new Timer( delay, new ActionListener() { public void actionPerformed(ActionEvent e) { Calendar now = Calendar.getInstance(); int day = now.get(Calendar.DAY_OF_MONTH); int mese = now.get(Calendar.MONTH)+1; int anno = now.get(Calendar.YEAR); int h = now.get(Calendar.HOUR_OF_DAY); int m = now.get(Calendar.MINUTE); int s = now.get(Calendar.SECOND); timeField.setText( "Data: " + day + "-" + mese + "-" + anno + " Ore: " + h + ":" + m + ":" + s); } });
JPanel panelPrincipale = new JPanel(); panelPrincipale.add (timeField);
getContentPane().add (panelPrincipale); pack(); setSize(500,100); }
/** Start the timer */ public void start() { timer.start(); }
public static void main(String[] args) { Runnable r = new Runnable() { public void run() { Interfaccia2 app = new Interfaccia2(); app.setVisible (true); app.start(); } }; SwingUtilities.invokeLater(r); } } </sscce>
 Signature Andrew Thompson http://www.athompson.info/andrew/
Sal - 31 Oct 2007 16:41 GMT [...]
> I ran 'your'* code for 8 hours on Win XP Pro using > Java 1.6.0_02**. Besides that, I also ran jconsole > (part of the 1.6 SDK, not sure of earlier versions). GREAT!!
> * You code was horrible. Ehm... now i think that you are right.
> *Please run it and confirm the same behaviour you > reported as a 'memory leak'.* Yes I ran it for two hour and the memory grows up to 15.824 KB (Task Manager Windows)
> OTOH, if your app. actually hits OutOfMemoryErrors, > we need to look more closely at what it is doing, and > (if my addled memory serves me well) what is happening > with any Image's and ImageIcon's.. Yes I've to look in another place the problem of my memory error (probably a memory leak ;), but i'm not a specialist i written this program day by day not looking to the correct code but looking to make it runs.
Now i have a program of 1300 lines of graphical interface and many more to control it and i don't know where i have to look! I need a tool that help me to find the problem, can you advice me a freeware one?
Another time Thanks to all person that use time to help me
Sal
Daniel Dyer - 31 Oct 2007 17:05 GMT > [...] >> I ran 'your'* code for 8 hours on Win XP Pro using [quoted text clipped - 12 lines] > Yes I ran it for two hour and the memory grows up to 15.824 KB (Task > Manager Windows) Forget about the Windows Task Manager, it's next to useless for these kind of measurements (as an aside, you'll notice that if you minimize the application window and restore it, the size will drop dramatically).
>> OTOH, if your app. actually hits OutOfMemoryErrors, >> we need to look more closely at what it is doing, and [quoted text clipped - 5 lines] > program day by day not looking to the correct code but looking to make > it runs. Follow Patricia's advice, set the maximum heap size to be just big enough (from Andrew's JConsole screenshots, it looks like even 3mb would be enough, certainly no more than 6mb). If you can't get the application to throw an OutOfMemoryError then you almost certainly don't have a memory leak. Of course, if you set it too low initially it will throw this error immediately. I'm assuming 3mb is enough to get it up and running.
Dan.
 Signature Daniel Dyer http://www.uncommons.org
Andrew Thompson - 01 Nov 2007 03:56 GMT >> [...] >>> I ran 'your'* code for 8 hours on Win XP Pro using ...
>> Yes I ran it for two hour and the memory grows up to 15.824 KB (Task >> Manager Windows) ... > >Forget about the Windows Task Manager, it's next to useless for these kind >of measurements ... Lew mentioned that earlier. Daniel mentioned it again, and I will add my agreement to both.
Don't use the Windows Task Manager as any sort of indication of what is happening to your app. How Windows goes about assigning memory to the JVM that runs your app., is a separate matter.
If the size of the JVM in the task manager actually grows too big to handle, that will cause a crash in Windows, but there is nothing that a Java application can do about that - it is a matter between Sun and Microsoft.
The tool I pointed you too earlier, jconsole, is one simple way to get a view into the memory used by a Java app. (somebody also pointed out the NetBeans Profiler, earlier, but I suspect jconsole is every bit good enough for this job). jconsole.exe should also be available on your local machine, assuming it has a recent JDK installed (I see it came with 1.5 as well). jconsole can be found in the bin directory of the JDK location.
Also, as suggested - severely limit the memory of the app. in testing, so that if a memory leak really exists, it will cause problems much sooner.
Until you can say you have seen *OutOfMemoryErrors,* I am inclined to believe there is *no memory leak.*
 Signature Andrew Thompson http://www.athompson.info/andrew/
Patricia Shanahan - 31 Oct 2007 22:43 GMT > [...] >> I ran 'your'* code for 8 hours on Win XP Pro using [quoted text clipped - 27 lines] > I need a tool that help me to find the problem, can you advice me a > freeware one? ...
Maybe it is time for some refactoring, with the objective of making the program cleaner and easier to decompose, as well as ensuring all GUI work is done in the event handling thread.
It is entirely possible that the refactoring will itself remove the problem. If it does not, you will have a better base for SSCCE construction. The SSCCE approach can be a good way of tracking down problems, even if you never post them to a newsgroup. The idea is to progressively simplify the program, removing everything that is not essential to reproducing the bug.
In your case, the test should be whether you get an OutOfMemoryError if you run the program with -Xmx set to a reasonable value. Any time you remove something, and the bug goes away, you have a new clue about what is going wrong.
Patricia
Lew - 31 Oct 2007 23:22 GMT Sal wrote:
>> Yes I ran it for two hour and the memory grows up to 15.824 KB (Task >> Manager Windows) This is not evidence of a memory leak. You have shown us NO evidence that there is a leak.
 Signature Lew
Mark Space - 01 Nov 2007 00:25 GMT > On 31 Ott, 13:10, "Andrew Thompson" <u32984@uwe> wrote: >> *Please run it and confirm the same behaviour you >> reported as a 'memory leak'.* > > Yes I ran it for two hour and the memory grows up to 15.824 KB (Task > Manager Windows) Just to re-iterate, you should reduce the heap size as much as possible, and run until you get an out of memory exception. Then copy the stack trace here so we can see it. Can't help you much until we see that error.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|