Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / November 2007

Tip: Looking for answers? Try searching our database.

REAL SSCCE of my graphical interface with memory leaks

Thread view: 
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 Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.