|
Quick Lists
|
|
Bug ID:
|
4254022
|
|
Votes
|
3
|
|
Synopsis
|
PERF: GridBagLayout inefficiency
|
|
Category
|
java:classes_awt
|
|
Reported Against
|
1.1
, 1.1.1
, 1.1.6
, 1.1.7
, 1.1.8
, 1.4.1
, kestrel
, 1.2beta4
, tiger-rc
|
|
Release Fixed
|
mustang(b24)
|
|
State
|
10-Fix Delivered,
bug
|
|
Priority:
|
4-Low
|
|
Related Bugs
|
4014289
,
4071278
,
4195986
,
4869906
,
4623196
,
5107980
|
|
Submit Date
|
14-JUL-1999
|
|
Description
|
We have profiled our Java program and one of
the places it is spending the most time is in
GridBagLayout allocating new arrays. For example:
GridBagLayoutInfo () {
minWidth = new int[GridBagLayout.MAXGRIDSIZE];
minHeight = new int[GridBagLayout.MAXGRIDSIZE];
weightX = new double[GridBagLayout.MAXGRIDSIZE];
weightY = new double[GridBagLayout.MAXGRIDSIZE];
}
This method is called many times. It allocates
arrays of MAXGRIDSIZE (512) ints and doubles.
Also there are other allocations of arrays of
[MAXGRIDSIZE] elements. MAXGRIDSIZE is a static final
int so a class can't even extend GridBagLayout and
change its value.
How about adding setMaxGridSize() to GridBagLayout,
or a new constructor GridBagLayout(int maxGridSize)?
(Review ID: 85571)
======================================================================
|
|
Work Around
|
N/A
|
|
Evaluation
|
We should change GridBagLayout to use a vector instead of a fixed array of
size 512. This is not only a waste of memory when small numbers of
components are in the Layout, but it limits the maximum grid to 512.
We have had complaints about both of these problems.
We need to clean up GridBagLayout and GridBagLayoutInfo to use Vectors
instead of the arrays.
xxxxx@xxxxx 1999-12-22
Because of a risk of breaking serialization with older versions and that both Vectors and ArrayList work with objects not int and double arrays causing quite a bit of extra code to be written for a slight performance gain this is being deffered until Tiger
xxxxx@xxxxx 2000-09-07
Comitting to tiger, as it should also fix 4623196.
xxxxx@xxxxx 2003-10-15
My original intention was to replace the int[] and double[] arrays in GridBagLayoutInfo with ArrayLists. However it turns out that a new GridBagLayoutInfo is created everytime the container is layed out. By putting off creation of the GridBagLayoutInfo until we know the width and height of the grid, we can create arrays of the exact size needed. This is a shorter-reaching and more compatible change (for instance, this doesn't break serialization). I still employed local ArrayLists during layout when the GridBagConstraints are being examined and before the grid size is known.
I've attached the modified code example from the JavaDoc (GridBagEx1) which I used to take some performance numbers. It shows the Frame and then does a series of resizes. Overall, it looks like runtime performance is a wash running with or without my fix. Really, though, it doesn't look like the allocation of arrays is really a hotspot at all. This may have been true in the 1.1.* days, but I think it's no longer the case.
On the bright side, OptimizeIt reports 33k less memory being used by int[]s, and the fix causes roughly one quarter the number of GCs:
java -verbosegc before:
$ c:/tiger/tiger/build/windows-i586/bin/java -verbosegc -cp . GridBagEx2
[GC 511K->211K(1984K), 0.0071006 secs]
[GC 723K->275K(1984K), 0.0045100 secs]
[GC 783K->282K(1984K), 0.0014622 secs]
[GC 793K->294K(1984K), 0.0005599 secs]
[GC 806K->279K(1984K), 0.0009201 secs]
[GC 790K->289K(1984K), 0.0005169 secs]
[GC 799K->291K(1984K), 0.0006515 secs]
[GC 802K->292K(1984K), 0.0005072 secs]
[GC 803K->296K(1984K), 0.0005159 secs]
[GC 805K->297K(1984K), 0.0005135 secs]
[GC 805K->298K(1984K), 0.0004632 secs]
[GC 810K->299K(1984K), 0.0005008 secs]
[GC 810K->306K(1984K), 0.0005099 secs]
[GC 818K->311K(1984K), 0.0005298 secs]
[GC 821K->310K(1984K), 0.0005345 secs]
[GC 822K->314K(1984K), 0.0004714 secs]
[GC 826K->300K(1984K), 0.0005099 secs]
[GC 812K->304K(1984K), 0.0005232 secs]
[GC 813K->306K(1984K), 0.0004495 secs]
[GC 814K->307K(1984K), 0.0004899 secs]
[GC 817K->308K(1984K), 0.0004619 secs]
[GC 817K->309K(1984K), 0.0005342 secs]
[GC 818K->311K(1984K), 0.0005230 secs]
[GC 822K->316K(1984K), 0.0004956 secs]
[GC 827K->321K(1984K), 0.0005094 secs]
[GC 833K->310K(1984K), 0.0004434 secs]
[GC 822K->312K(1984K), 0.0005476 secs]
java -verbosegc after:
$ c:/tiger/tiger/build/windows-i586/bin/java -verbosegc -cp . GridBagEx2
[GC 511K->211K(1984K), 0.0071040 secs]
[GC 723K->286K(1984K), 0.0046603 secs]
[GC 798K->296K(1984K), 0.0020308 secs]
[GC 808K->297K(1984K), 0.0009177 secs]
[GC 809K->298K(1984K), 0.0007943 secs]
[GC 810K->299K(1984K), 0.0009182 secs]
[GC 811K->299K(1984K), 0.0008974 secs]
[GC 811K->301K(1984K), 0.0007395 secs]
Also (other practical limits notwithstanding), it's now possible to create a GridBagLayout with > 512 Components wide and high. The following test used to throw an ArrayIndexOutOfBoundsException. It now runs to completion, provided you sufficently increase the heap size (:
// Flex the new GridBagLayout with more than 512 items wide & high
import java.awt.*;
public class BigGBL {
public static final int ITEMS = 600;
public static void main(String[] args) {
GridBagLayout gbl = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
Panel panel = new Panel();
panel.setLayout(gbl);
for (int i = 0; i < ITEMS; i++) {
for (int j = 0; j < ITEMS; j++) {
gbc.gridx = i;
gbc.gridy = j;
panel.add(new Label("Label"), gbc);
}
}
panel.doLayout();
}
}
xxxxx@xxxxx 2003-10-20
|
|
Comments
|
Submitted On 06-AUG-1999
rfinch
This is especially prevalent when using Swing menus, as each JPopupMenu uses a
GridLagLayout to layout the menu items.
Also, GridBagLayout allocates a Hashtable for the components and the
HashtableEntry items also take a fair bit of memory.
JPopupMenu should also be changed not to use GridBagLayout, as the enhancement
suggested above doesn't get around this problem. The user has no control over
the size of the grid.
Might it not be a better idea to grow the grid as necessary when components are
added.
Submitted On 09-JAN-2000
oleg
Using Vectors instead of arrays might really slow down the layout process.
Please consider using of arrays, but dynamically expanded.
Submitted On 31-JUL-2000
nienhs
the problem still occurs in j2sdk 1.3.0.
Submitted On 27-MAR-2001
adriskill
arggghhhhh!
Submitted On 27-MAY-2001
kdmason
This is marked as an RFE? It's an out and out bug. What a
cop out! Furthermore, the bug is almost 2 years old, and
fairly trivial to fix. Dynamic
rrays/ArrayLists/LinkedLists/Vectors could all be used, or
you could just add another constructor where the user
specified the MAXGRIDSIZE.
Submitted On 01-AUG-2001
cs1mjp
It is not just a performance gain that is at stake. I have
an application that is ready to go out in two weeks that
breaks because the user can add an indeterminate number of
entries to a JComponent viewed from within a JScrollPane.
As soon as the number exceeds 512 (and there are 18
components added for each new object the user selects,
which limits me to only about 28) the thing crashes!!
I would rather you broke serialization and fixed this!
Submitted On 22-OCT-2001
oleg
We've replaced GridBagLayout with our own version which
dynamically expands arrays and this saved about 3M of the
javaw.exe process memory.
Submitted On 30-OCT-2001
cs1mjp
How can you replace with our own version without replacing
all of swing? If you just replace just GridBagLayout, you
probably break your agreement with Sun.
Best submit your modified version to Sun for inclusion in
1.4.
Submitted On 02-JUN-2003
limahl
It's has been 3.5 years since the original bug report.
This bug still present in 1.4.1. It's about time it is fixed
once and for all. This memory leak, however insignificant
per instance makes a big difference if your app uses
lots of layout managers.
Submitted On 17-SEP-2003
jakubiak
It also makes it impossible to add more than 512 rows or
columns to a component using the GridBagLayout, a case that
I have to solve.
Submitted On 18-FEB-2004
GridBagLayout
This is still pain in butt, one of our oprations critical
application has devleoped using GridBagLayout and
now the necessity increased to put more than 512
components which started throwing an exception.
What's the solution guys?
Submitted On 10-JUL-2004
vy_ho
I thought this is fixed in 1.5 (5.0)
Submitted On 17-SEP-2004
Matthias_Mann
A solution was found one year ago. Why is this still not in J2SE 1.5.0 RC ?
Just today the limitation to 512 has caused us many headaches.
Submitted On 27-SEP-2004
acroft
I'm a little bit confused as to whether gridbags of size > 512 are supposed to work in 1.5 RC or not. They were working in build 1.5.0-beta-b32c but not in build 1.5.0-rc-b63. What's going on here?
Submitted On 09-OCT-2004
vy_ho
Looking at the source code today, which is the source of the released JDK 5.0, the gridbaglayout seems to revert back to 512. This shocks me. I am not sure what is going on. Please someone at Sun give us a hint.
Submitted On 12-OCT-2004
croftd
According to bug 5107980 the fix was backed out because of regressions the fix introduced. Sun is claiming smaller memory footprint with 5.0, but I wonder if there numbers are based on having the fix in or out. I'm very dissapointed. I can't believe this is still a problem after FIVE YEARS!
Submitted On 27-SEP-2006
lrussell@ccipher.com
Is this bug fixed in current release of 5.0 or not? Some of your docs say yes others say no, which is it?
Submitted On 28-SEP-2006
thetan
This defect is fixed in JDK6.0, not in JDK5.0.
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |