-
Bug
-
Resolution: Fixed
-
P4
-
1.4.2
-
b03
-
x86
-
linux
-
Verified
Name: jl125535 Date: 02/24/2004
FULL PRODUCT VERSION :
java version "1.5.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32c)
Java HotSpot(TM) Client VM (build 1.5.0-beta-b32c, mixed mode)
java version "1.4.2_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_03-b02)
Java HotSpot(TM) Client VM (build 1.4.2_03-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux ghoul 2.6.2-1-k7 #1 Sat Feb 7 17:02:15 EST 2004 i686 GNU/Linux
Debian/unstable.
A DESCRIPTION OF THE PROBLEM :
When swing (and maybe awt) is used, a lot of strings in memory are font names.
For a big application this is not a big problem (~40kB data is not very
much). For a small application that does not do any drawing, storing this
information is quite unneccessary and makes the memory usage bigger than
needed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a small program that opens a single jframe will cause high memory usage.
Source for such a program is in this bug report.
Run that program in a debugger that can inspect the strings that are used. I use jmp, it is available from http://www.khelekore.org/jmp/
Start the profiling session:
java -Xrunjmp:nomethods,nomonitors,noobjects JFrameTest
Call garbage collect (using the jvmpi to force collection) .
Enable object profiling
Bring up a window with all strings and check what strings there are in memory.
Dump strings to file for more inspection later on.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Lower memory usage. Why are font names kept around when they are unused and available on request from the window system. Most of the fonts will never be used so why keep the names?
ACTUAL -
High memory usage.
In the files with all strings that could not be garbage collected there are lots of strings on the format: "/home/robo/pkg/java/j2sdk1.5.0-beta/jre/lib/fonts/LucidaSansRegular.ttf " and
"-b&h-lucidatypewriter-medium-r-normal-sans-*-%d-*-*-m-*-iso8859-1". Some of the strings exists several times (_note_: not String objects, but distinct char[]).
There are also a lot of minor variations in the font names:
"LucidaSansDemiOblique.ttf -b&h-lucidasans-bold-i-normal-sans-0-0-0-0-p-0-iso8859-1" and
"LucidaSansDemiOblique.ttf -b&h-lucidasans-bold-i-normal-sans-0-0-0-0-p-0-iso8859-2" differ only in the last character.
For 1.4.2_03, Top reports the memory usage as this:
1449 robo 25 0 212m 16m 44m S 0.0 3.3 0:00.31
java
/proc/1449/status gives this (and some more:
FDSize: 256
Groups: 1000 24 29 44
VmSize: 218084 kB
VmLck: 0 kB
VmRSS: 16788 kB
VmData: 172420 kB
VmStk: 44 kB
VmExe: 24 kB
VmLib: 11460 kB
Threads: 12
For 1.5.0-beta, Top reports this:
1511 robo 16 0 254m 18m 66m S 0.0 3.6 0:00.17 java
and /proc/1551/status give this:
Groups: 1000 24 29 44
VmSize: 260236 kB
VmLck: 0 kB
VmRSS: 18864 kB
VmData: 190020 kB
VmStk: 2036 kB
VmExe: 56 kB
VmLib: 8380 kB
Threads: 12
1.5-beta seems to use slightly more memory.
When profiling there are no big differences between 1.4.2 and 1.5-beta,
1.5-beta starts up with a little less used heap. The discussion from
now on is based on 1.5, but 1.4 seems to use about the same resources
for fonts.
Jvmpi reports that 1.5-beta uses ~1781740 bytes of memory at startup
it keeps fluctuating due to the fact that sun.awt.X11.XToolkit calls
dispatchEvent (sun.awt.X11.XAnyEvent) and allocates a few objects
continously (every few seconds).
Forcing garbage collection with the jvmpi-function brings the java heap
down to 373344 bytes.
In the heap there are 618 java.lang.String objects and 551 char[]
The String occupies 14832 bytes and the char[] 87808 bytes (27%
of the java heap).
If I have counted correctly there are 268 char[] that hold font
names (I may have missed a few). I guess that the number depends
on the available fonts on the system so it could vary quite much.
Both of these char[] have many characters, according to gnumeric it seems
to be 28188 bytes used for the char[].
There are 2 types of string, file names for true type fonts
/home/robo/pkg/java/j2sdk1.5.0-beta/jre/lib/fonts/LucidaTypewriterBoldOblique.ttf
and font names.
-b&h-lucidatypewriter-medium-i-normal-sans-*-%d-*-*-m-*-iso8859-1
I can send you a full list of the char[] data if you want to.
I have not had the time to trace the Strings very much, Most are held my
HashMap$Entry, Hashtable$Entry or Object[]. 40 Strings seems to be keept
by sun.font.CompositeFont, 12 by sun.font.FontManager$FontRegistrationInfo.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.swing.*;
public class JFrameTest {
public static void main (String[] args) {
JFrame jf = new JFrame ();
jf.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
jf.setSize (300, 300);
jf.setVisible (true);
}
}
---------- END SOURCE ----------
(Incident Review ID: 239765)
======================================================================
FULL PRODUCT VERSION :
java version "1.5.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32c)
Java HotSpot(TM) Client VM (build 1.5.0-beta-b32c, mixed mode)
java version "1.4.2_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_03-b02)
Java HotSpot(TM) Client VM (build 1.4.2_03-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux ghoul 2.6.2-1-k7 #1 Sat Feb 7 17:02:15 EST 2004 i686 GNU/Linux
Debian/unstable.
A DESCRIPTION OF THE PROBLEM :
When swing (and maybe awt) is used, a lot of strings in memory are font names.
For a big application this is not a big problem (~40kB data is not very
much). For a small application that does not do any drawing, storing this
information is quite unneccessary and makes the memory usage bigger than
needed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a small program that opens a single jframe will cause high memory usage.
Source for such a program is in this bug report.
Run that program in a debugger that can inspect the strings that are used. I use jmp, it is available from http://www.khelekore.org/jmp/
Start the profiling session:
java -Xrunjmp:nomethods,nomonitors,noobjects JFrameTest
Call garbage collect (using the jvmpi to force collection) .
Enable object profiling
Bring up a window with all strings and check what strings there are in memory.
Dump strings to file for more inspection later on.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Lower memory usage. Why are font names kept around when they are unused and available on request from the window system. Most of the fonts will never be used so why keep the names?
ACTUAL -
High memory usage.
In the files with all strings that could not be garbage collected there are lots of strings on the format: "/home/robo/pkg/java/j2sdk1.5.0-beta/jre/lib/fonts/LucidaSansRegular.ttf " and
"-b&h-lucidatypewriter-medium-r-normal-sans-*-%d-*-*-m-*-iso8859-1". Some of the strings exists several times (_note_: not String objects, but distinct char[]).
There are also a lot of minor variations in the font names:
"LucidaSansDemiOblique.ttf -b&h-lucidasans-bold-i-normal-sans-0-0-0-0-p-0-iso8859-1" and
"LucidaSansDemiOblique.ttf -b&h-lucidasans-bold-i-normal-sans-0-0-0-0-p-0-iso8859-2" differ only in the last character.
For 1.4.2_03, Top reports the memory usage as this:
1449 robo 25 0 212m 16m 44m S 0.0 3.3 0:00.31
java
/proc/1449/status gives this (and some more:
FDSize: 256
Groups: 1000 24 29 44
VmSize: 218084 kB
VmLck: 0 kB
VmRSS: 16788 kB
VmData: 172420 kB
VmStk: 44 kB
VmExe: 24 kB
VmLib: 11460 kB
Threads: 12
For 1.5.0-beta, Top reports this:
1511 robo 16 0 254m 18m 66m S 0.0 3.6 0:00.17 java
and /proc/1551/status give this:
Groups: 1000 24 29 44
VmSize: 260236 kB
VmLck: 0 kB
VmRSS: 18864 kB
VmData: 190020 kB
VmStk: 2036 kB
VmExe: 56 kB
VmLib: 8380 kB
Threads: 12
1.5-beta seems to use slightly more memory.
When profiling there are no big differences between 1.4.2 and 1.5-beta,
1.5-beta starts up with a little less used heap. The discussion from
now on is based on 1.5, but 1.4 seems to use about the same resources
for fonts.
Jvmpi reports that 1.5-beta uses ~1781740 bytes of memory at startup
it keeps fluctuating due to the fact that sun.awt.X11.XToolkit calls
dispatchEvent (sun.awt.X11.XAnyEvent) and allocates a few objects
continously (every few seconds).
Forcing garbage collection with the jvmpi-function brings the java heap
down to 373344 bytes.
In the heap there are 618 java.lang.String objects and 551 char[]
The String occupies 14832 bytes and the char[] 87808 bytes (27%
of the java heap).
If I have counted correctly there are 268 char[] that hold font
names (I may have missed a few). I guess that the number depends
on the available fonts on the system so it could vary quite much.
Both of these char[] have many characters, according to gnumeric it seems
to be 28188 bytes used for the char[].
There are 2 types of string, file names for true type fonts
/home/robo/pkg/java/j2sdk1.5.0-beta/jre/lib/fonts/LucidaTypewriterBoldOblique.ttf
and font names.
-b&h-lucidatypewriter-medium-i-normal-sans-*-%d-*-*-m-*-iso8859-1
I can send you a full list of the char[] data if you want to.
I have not had the time to trace the Strings very much, Most are held my
HashMap$Entry, Hashtable$Entry or Object[]. 40 Strings seems to be keept
by sun.font.CompositeFont, 12 by sun.font.FontManager$FontRegistrationInfo.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.swing.*;
public class JFrameTest {
public static void main (String[] args) {
JFrame jf = new JFrame ();
jf.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
jf.setSize (300, 300);
jf.setVisible (true);
}
}
---------- END SOURCE ----------
(Incident Review ID: 239765)
======================================================================