Memory problem with JTextFields

Hello,

I have a wierd problem with JTextField and the memory.

I need to fill a JPanel with different Components (including JTextFields), then do some calculation, remove the Components and filling the JPanel again.

When i so this too often my i get an OutOfMemory Exception. I narrowed to problem down and wrote a small sample program to demonstrate the problem.

When i call the method doIT (where the Panel is repeatedly filled) from the main-function everything works fine, but when it is called as a result from the GUI-Button-Event the memory for the JTextFields is not freed (even the call of the Garbage collector changes nothing)

When i only use JButtons to fill the Panel everything works fine.

Has anyone an idea why this problem occurs and how i can work around it?

[Edit] I tested it whith java 1.5.0_06, 1.5.0_11, 1.6.0_02

Thanks

Marc

import java.awt.Frame;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.lang.management.ManagementFactory;

import java.lang.management.MemoryUsage;

import javax.swing.JButton;

import javax.swing.JDialog;

import javax.swing.JPanel;

import javax.swing.JTextField;

publicclass MemoryTestDLGextends JDialog{

public MemoryTestDLG(Frame owner){

// create Dialog with one Button that calls the testMethod

super(owner);

JButton b =new JButton("doIT ...");

b.addActionListener(new ActionListener(){

publicvoid actionPerformed(ActionEvent e){

doIT();

setVisible(false);

}

});

getContentPane().add(b);

pack();

}

publicvoid doIT(){

// Testmethod that fills a JPanel 20 times with Components and clears it

// again

JPanel p =new JPanel();

long memUse1 = 0;

long memUse2 = 0;

long memUseTemp = 0;

for (int count = 0; count < 20; count++){

// Clear the panel

p.removeAll();

// Get memory usage before the task

Runtime.getRuntime().gc();

memUse1 = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()

.getUsed();

// Fill Panel with components

for (int i = 0; i < 200; i++){

// The Buttons seem to be released without any problem

p.add(new JButton("test" + Math.random()));

// JTextFields are not released when used from the dialog.

p.add(new JTextField("test " + Math.random()));

}

// get memory usage after the task

Runtime.getRuntime().gc();

memUseTemp = memUse2;

memUse2 = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()

.getUsed();

// print Memory results

System.out.println("Memory Usage: " + f(memUse1) +"->"

+ f(memUse2) +" [ Used:" + f(memUse2 - memUse1)

+" ] [ Freed: " + f(memUseTemp - memUse1) +"]");

}

}

public String f(long m)// formats the output

{

String s ="" + m;

while (s.length() < 8)

s =" " + s;

return s;

}

publicstaticvoid main(String[] args){

MemoryTestDLG d =new MemoryTestDLG(null);

System.out

.println(" Direct Call (all is OK) -");

d.doIT();// Memory is freed with every call to JPanel.removeAll()

System.out

.println(" Call from Dialog (memory is not freed) -");

// The Memory keeps blocked

d.setModal(true);

d.setVisible(true);

System.exit(0);

}

}

Message was edited by:

marcvomorc

[6114 byte] By [marcvomorca] at [2007-11-27 11:41:26]
# 1

I've run your code almost fifteen times and have not run out memory. I realised the memory is only being released when the objects are not visible on the screen. However, when the button is clicked, there is huge (in the 800000's) amount memory released at once. Also running Task Manager, it shows that amount of memory assigned to the app is virtually the same all through. Maybe it has something to do with your system. I'm running JDK 6.0 on Windows Vista 32bit, with 1Gb RAM

Here is your slightly modified doIT method. modified for graphical display only.

public void doIT() {

// Testmethod that fills a JPanel 20 times with Components and clears it

// again

JPanel p = new JPanel( new GridLayout(0,2) );

long memUse1 = 0;

long memUse2 = 0;

long memUseTemp = 0;

for (int count = 0; count < 20; count++) {

// Clear the panel

p.removeAll();

p.validate();

p.repaint();

// Get memory usage before the task

Runtime.getRuntime().gc();

memUse1 = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()

.getUsed();

// Fill Panel with components

for (int i = 0; i < 200; i++) {

// The Buttons seem to be released without any problem

p.add(new JButton("test" + Math.random()));

// JTextFields are not released when used from the dialog.

p.add(new JTextField("test " + Math.random()));

}

// get memory usage after the task

Runtime.getRuntime().gc();

memUseTemp = memUse2;

memUse2 = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()

.getUsed();

// print Memory results

System.out.println("Memory Usage: " + f(memUse1) + "->"

+ f(memUse2) + " [ Used:" + f(memUse2 - memUse1)

+ " ] [ Freed: " + f(memUseTemp - memUse1) + "]");

}

getContentPane().add( new JScrollPane(p), BorderLayout.CENTER);

getContentPane().validate();

getContentPane().repaint();

}

ICE

icewalker2ga at 2007-7-29 17:38:09 > top of Java-index,Desktop,Core GUI APIs...
# 2

Thank you for your answer,

In this sample the programm does not run out of memory. But when you look at the output you see, that in the first run (direct call) the memory ist freed immediately when tha panel is cleared but in the second run (from the Button) the memory usage is getting bigger and bigger. Wenn you change the number of components to 2000 (4000)

//... ....

// Fill Panel with components

for (int i = 0; i < 2000; i++) {

// The Buttons seem to be released without any problem

//... ...

and use the default memory settings (69mb heap) the programm runns out of memory.

I get the following output:

Direct Call (all is OK) -

Memory Usage:445504-> 8121016 [ Used: 7675512 ] [ Freed: -445504]

Memory Usage:617352-> 8114336 [ Used: 7496984 ] [ Freed: 7503664]

Memory Usage:810488-> 8491768 [ Used: 7681280 ] [ Freed: 7303848]

Memory Usage:943704-> 8114976 [ Used: 7171272 ] [ Freed: 7548064]

Memory Usage:836760-> 8505072 [ Used: 7668312 ] [ Freed: 7278216]

Memory Usage:978352-> 8114784 [ Used: 7136432 ] [ Freed: 7526720]

Memory Usage:835552-> 8498288 [ Used: 7662736 ] [ Freed: 7279232]

Memory Usage:977096-> 8114312 [ Used: 7137216 ] [ Freed: 7521192]

Memory Usage:835640-> 8498376 [ Used: 7662736 ] [ Freed: 7278672]

Memory Usage:977296-> 8115000 [ Used: 7137704 ] [ Freed: 7521080]

Memory Usage:835392-> 8504872 [ Used: 7669480 ] [ Freed: 7279608]

Memory Usage:976968-> 8115192 [ Used: 7138224 ] [ Freed: 7527904]

Memory Usage:836224-> 8501624 [ Used: 7665400 ] [ Freed: 7278968]

Memory Usage:977840-> 8115120 [ Used: 7137280 ] [ Freed: 7523784]

Memory Usage:835664-> 8498256 [ Used: 7662592 ] [ Freed: 7279456]

Memory Usage:976856-> 8114384 [ Used: 7137528 ] [ Freed: 7521400]

Memory Usage:835784-> 8502848 [ Used: 7667064 ] [ Freed: 7278600]

Memory Usage:977360-> 8114592 [ Used: 7137232 ] [ Freed: 7525488]

Memory Usage:835496-> 8502720 [ Used: 7667224 ] [ Freed: 7279096]

Memory Usage:976440-> 8115128 [ Used: 7138688 ] [ Freed: 7526280]

Call from Dialog (memory is not freed) -

Memory Usage:866504-> 8784320 [ Used: 7917816 ] [ Freed: -866504]

Memory Usage: 7480760->14631152 [ Used: 7150392 ] [ Freed: 1303560]

Memory Usage: 14245264->22127104 [ Used: 7881840 ] [ Freed:385888]

Memory Usage: 19302896->27190744 [ Used: 7887848 ] [ Freed: 2824208]

Memory Usage: 27190744->35073944 [ Used: 7883200 ] [ Freed:0]

Memory Usage: 31856624->39740176 [ Used: 7883552 ] [ Freed: 3217320]

Memory Usage: 39740176->47623040 [ Used: 7882864 ] [ Freed:0]

Memory Usage: 44410480->52293864 [ Used: 7883384 ] [ Freed: 3212560]

Memory Usage: 52293864->58569304 [ Used: 6275440 ] [ Freed:0]

Memory Usage: 58569304->64846400 [ Used: 6277096 ] [ Freed:0]

Exception occurred during event dispatching:

java.lang.OutOfMemoryError: Java heap space

when I outcomment the adding of the JButtons the amount of freed memory is 0 in the second run. So my guess is, that there is a problem with freeing the memory for the JTextFields.

Memory Usage:447832-> 6509960 [ Used: 6062128 ] [ Freed: 6332768]

Memory Usage:722776-> 6785632 [ Used: 6062856 ] [ Freed: 5787184]

Call from Dialog (memory is not freed) -

Memory Usage:468880-> 6770240 [ Used: 6301360 ] [ Freed: -468880]

Memory Usage: 6770240->13016264 [ Used: 6246024 ] [ Freed:0]

Memory Usage: 13016264->19297080 [ Used: 6280816 ] [ Freed:0]

Memory Usage: 19297080->25570152 [ Used: 6273072 ] [ Freed:0]

Memory Usage: 25570152->31849160 [ Used: 6279008 ] [ Freed:0]

Memory Usage: 31849160->38124368 [ Used: 6275208 ] [ Freed:0]

Memory Usage: 38124368->44402072 [ Used: 6277704 ] [ Freed:0]

Memory Usage: 44402072->50677928 [ Used: 6275856 ] [ Freed:0]

Memory Usage: 50677928->56955880 [ Used: 6277952 ] [ Freed:0]

Memory Usage: 56955880->63232152 [ Used: 6276272 ] [ Freed:0]

Exception occurred during event dispatching:

java.lang.OutOfMemoryError: Java heap space

Additionally the JPanel I am using is not displayed on the screen. It stays invisible the whole time, but i cannot work around that, because the calculation is depending on the values being in components on the JPanel)

Marc

marcvomorca at 2007-7-29 17:38:09 > top of Java-index,Desktop,Core GUI APIs...
# 3

Well I'd suggest you switch to less memory hungry approach and use a JTable or some other multiple row data component to store the values for calculations and not result to using multiple text fields. With JTable you can display up to about 30000 rows without too much memory loss. (Unless this is not your requirement.). You could even only use the TableModel as your data store since you do not need the display and do you calculations with that.

ICE

icewalker2ga at 2007-7-29 17:38:09 > top of Java-index,Desktop,Core GUI APIs...