REAL SSCCE of my graphical interface with memory leaks

S

Sal

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>
 
M

Mark Space

Sal said:
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.
 
R

Roedy Green

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
 
R

Roedy Green

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();
 
R

Roedy Green

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
 
M

Mark Space

Roedy said:
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.
 
S

Sal

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
 
L

Lew

Sal said:
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?
 
L

Lew

Roedy said:
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.

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

Mark Space

Sal said:
first of all thanks to all!


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?


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

Sal

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?

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
 
S

Sal

Roedy Green wrote:
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.

Please, can you post an example of correct Swing programming?
I'm not sure to understand the problem...

Thanks

Sal
 
P

Patricia Shanahan

Sal said:
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

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
 
A

Andrew Thompson

Sal said:

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>

--
Andrew Thompson
http://www.athompson.info/andrew/

Message posted via JavaKB.com
http://www.javakb.com/Uwe/Forums.aspx/java-general/200710/1
 
L

Lew

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?
 
R

RedGrittyBrick

Lew said:


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
 
S

Sal

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
 
D

Daniel Dyer

Ehm... now i think that you are right.


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

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top