Submitted On 11-OCT-2002
condass
We are having the same problem when using JDOM in the
1.4.1 environment. We process huge XML documents on our
servers and have found that we exceed the maximum physical
memory on our servers when using 1.4.1. Using -Xrunhprof I
can see that there is a leak associated with the StringBuffer
class. We will be staying on 1.3.1 until the problem is
resolved.
Submitted On 14-NOV-2002
davey
With the old VM:
java version "1.4.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build
1.4.0_02-b02)
Java HotSpot(TM) Client VM (build 1.4.0_02-b02, mixed mode)
Our server takes 6 MB when it comes up
(Runtime.totalMemory()-Runtime.freeMemory()).
After parsing an XML doc w/ JDM it's up to 20MB via
the same calculation.
With the new VM:
c:\dev\v52pb>java -version
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build
1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed
mode)
The process takes up 24M to start and to parse the
XML doc takes ...forever..and uses approx 250MB.
Amazing huh?
Submitted On 15-NOV-2002
corby
We use JDOM and got completely hosed by this bug. We are
backing JDK 1.4.1 out of our production environment now.
Submitted On 15-NOV-2002
ericburke
I'm pretty sure this leak is causing problems for us. We must
restart our app server every single night now that we are on
Java 1.4.1. We had to increase our heap size for all of our
client apps, as well, and still run out of memory after about a
day of usage. When will this be fixed?
Submitted On 18-NOV-2002
osbald
JDOM suffers horribly from this bug, which isn’t good news for
1.4.1 as its used widely behind the sense in many of the more
popular third-party java apps, including a couple of mine.
Development on JDOM seems to have slowed significantly
(due to the developers workloads, fame & fortune - rock & roll
lifestyle etc..) but there is a patched version of JDOM beta9
which can be checked out from the JDOM CVS repository –
one of the enhancements is a patch specifically for this bug..
I’ve been using beta9 for just over a month without any
significant problems, and no more spurious “out of memory
exceptions” from 1.4.1..
Submitted On 05-DEC-2002
bestsss
Workaround:... [ broken code will not be fixed, though :( ]
use StringBuffer.substring(0) instead of toString()
when sharing StringBuffer.
the method allocated exactly as needed bytes for the
returned String.
Submitted On 27-DEC-2002
DouglasBlair
I needed a PrintStream with UTF-8 output encoding to
generate flatfiles from my XML, so I needed 1.4.x. The
workaround with substring() helped. This is a serious bug
and ought to be fixed in 1.4.1_02. My .02, anyways...
Submitted On 09-JAN-2003
tupari
Why are you wating for Tiger???? That won't be out until the
end of 2003! It is simple to make the toString() the
equivalent of substring(0)
Submitted On 13-JAN-2003
dserodio
I agree this is a serious showstopper for 1.4.1. Waiting
until Tiger to fix it will make 1.4 simply useless for lots
of people (myself included).
Submitted On 23-JAN-2003
aanecito
Seems as if this would prevent usage of the JVM sun may be
thinking of using for the Windows release that was/is to occur
in the next 120 days? I intend not to recommend the upgrade
to my company and I am a big java supporter. This scares me
a lot!
Submitted On 27-JAN-2003
bestsss
the workaround: substring(0) is NOT replacer of toString().
this will result of huge drawback, because creating every
String would require double memory/room (and much more work
of garbage collector).
Actually the vast majory of programs dont share StringBuffer
(or they do it w/ same length Strings), so they are not
affected by the bug.
Besides, I never use StringBuffer w/ sharing. This always
results (even w/o the bug) in slower operation due to sync.
A class called com.xxx.util.AsynchStringBuffer is a
replacer. Since Strings are always copied (when shared)
there is no using utilizing a java.lang.StringBuffer in such
cases.
Submitted On 31-JAN-2003
ChristianHujer
I think this is an immediate must fix!
Using JDK 1.4.1, the default heap size is already not enough
when simply invoking ant to transform 15-20 XML files using
Xalan and Xerces. With JDK 1.4.0 there are no memory problems.
I had to increase my heap size to 256 MB to get medium
transformations working. Larger transformations require 512
to 1024 MB heap size.
This simply *must not* be.
Submitted On 10-FEB-2003
tahasam
Why is this not being fixed in Mantis (1.4.2)? Mantis will be
out early this year. This must NOTwait till Tiger (1.5). Tiger is
a year away!
Submitted On 11-FEB-2003
passwordp
Gafter, I really don't care what the spec. says.
StringBuffer.toString() is a special case of
StringBuffer.substring(x), where x = 0. Consequently, the
effects of StringBuffer.substring(0) and StringBuffer.toString()
should be identical. I would therefore argue that the spec. is
inconsistent. As the spec. is inconsistent, fix the code now,
and the spec later.
Also, why is this fix too big for a maintenance release? The
bug was introduced in a maintenance release - so why not
remove it in a maintenance release?!
Submitted On 11-FEB-2003
passwordp
WHAT ARE YOU GUYS - MORONS??? This is so incredibly easy
to fix (calling it a quick win would be an understatement) -
release it in 1.4.2 for Christs sake!
Submitted On 11-FEB-2003
mangri
This is a very annoying bug since every serious application
using jdom does not work on 1.4.1.
Regarding jdom a simple workaround in the jdom-b8 source
can help you out:
Update flushCharacters in org.jdom.input.SaxHandler.java -
see the "// mg" - "// gm" tagged section:
---------------------------------------------
protected void flushCharacters() throws SAXException {
if (textBuffer.length() == 0) {
previousCDATA = inCDATA;
return;
}
/*
* Note: When we stop supporting JDK1.1, use
substring instead
String data = textBuffer.substring(0);
*/
// mg: Because of java 1.4.1
// String data = textBuffer.toString();
String data = textBuffer.substring(0);
// gm
textBuffer.setLength(0);
---------------------------------------------
Submitted On 11-FEB-2003
gafter
The fix is only "easy" if you're not the one that has to do it.
The fact of the matter is that the old code didn't satisfy
the specification for StringBuffer because toString() changed
the capacity(), which it is not allowed to do. The "easy" fix
is to always copy the characters from the StringBuffer in
toString(), but that has a significant performance impact
on all clients. The current implementation is correct while the
old one wasn't. The best fix will be to rework the way
strings and
string buffers work together, or to change the spec for
toString()
so it is allowed to change the capacity, but either is a
larger change
than should go into a maintenance release.
If this problem affects your code, then rewrite your code to
stop
reusing StringBuffers.
Submitted On 14-FEB-2003
Parkway
// If newLength is zero, assume the StringBuffer is being
// stripped for reuse; Make new buffer of default size
value = new char[16];
shared = false;
Perhaps you should keep track of the last requested
capacity. Or at least document the pros and cons of
setLength(0), so that people don't use it inappropriately.
Submitted On 24-FEB-2003
wmshub
Actually, there does seem to be as easy fix that should make
everybody happy; the requirements seem to be:
- toString() should not change string buffer capacity. Until
1.4.1 it did.
- toString() should not always copy the buffer, which would
hammer the GC badly on a lot of applications. It has never
done this.
- Fix the *@!$# memory leak introduced in 1.4.1.
Note that the memory leak only shows up when you have a
high-capacity short-length string buffer and you call
toString(). My solution? Look at this:
public void toString() {
if (length() * 2 <= capacity()) {
sharedToString();
} else {
copyingToString();
}
}
See the point? If the string buffer is huge, and the string
is small, copy it. If the capacity and length are close,
share it. That way you don't make needless copies and fill
up memory with temporary objects, but you also don't fill up
memory with huge character arrays when your strings only use
the first few characters!
What is so hard about this, that it can't get into Mantis?
Am I being blind here, and there is some reason my easy fix
won't work?
Submitted On 11-MAR-2003
werezak
I wonder if Sun is reusing StringBuffers in the -Xrunprof
feature. My properly working application goes "out of
memory" if I use this option.
Submitted On 17-MAR-2003
jacyg
This has to be one of the most ridiculous bugs I've ever
seen. With XML so prevalent, and most people using tools
and utilities that they don't have direct control over, an
admonishment to "don't reuse StringBuffers" is almost
arrogantly insulting. Does Sun have some sort of desire for
people to not use 1.4.1+ for real world applications???
Real world applications make use of libraries written by
other people--it's asinine to expect that people are going
to entirely reengineer their applications to work around
this bug, especially since it didn't exist before (yes, it's
lovely that you fixed the *other* bug that existed, bravo,
but let's give some thought to relative severity here, shall
we??).
Submitted On 18-MAR-2003
PeBecker
We had an example where loading a 500kB XML file using
JDOM's SAXBuilder needed 500MB+ of heap size, which is a
no-go for deployment of the app. Current workaround is using
the DOMBuilder instead, but that is not a satisfying
solution. Not supporting 1.4.1 isn't satisfying either, we
are talking about an out-of-the-box product and we strongly
dislike playing these "don't use this JDK, don't use that
JDK" games. Customers blame use for bad support if that happens.
Submitted On 24-MAR-2003
bobHein
This really needs to be fixed by 1.4.2 at the latest; it is
preventing us from updating from 1.4.0 to 1.4.1!!
Submitted On 31-MAR-2003
synkronix
Could this perhaps be addressed in an alternate manner?
Removing sharing seems like a bad idea. Replacing the
backing array seems like a bad idea.
Just an idea. How about supporting array size modification at
the array object, adding a setLength(int) method to the array
object? (This may indeed require magic by the JVM; perhaps
it would only support decreasing the size, or resizing within
the original allocation size, depending on how it's implemented
at the lower level.)
In such a case, setLength(int) would be supported directly on
the backing array in StringBuffer (and many other locations).
The object reference would remain intact.
This is an operation I have to do on my own arrays quite
often, so having this supported as a method on the array
object itself would be handy in general. (A fill method on
arrays would also be quite useful.) Who said length() could
be the only method ever defined for arrays...
Submitted On 02-APR-2003
jeffcampbell
Because of this issue, we have been getting a lot of out of
memory errors in our program. To solve this, we are forced
to distribute our software with the 1.4.0 version of java
instead of the 1.4.1 version.
FYI We are using JDOM, which uses the StringBuffer object
Submitted On 03-APR-2003
thib_gc
I voted for this bug some time ago, because I read compelling
arguments from all of you here (thanks for sharing). Today,
this bug hit me where I was expecting it the least. The
following snippet of code caused a StackOverflowError:
// Start
ClassLoader loader = this.getClass().getClassLoader();
contentPane.add(new JLabel(new ImageIcon
(loader.getResource("images/my_icon.png"))),
BorderLayout.CENTER);
// End
And why? Well, apparently, the intermediate URL generated
by the class loader gets parsed somewhere in
java.net.URLStreamHandler which then calls toString in
java.lang.StringBuffer. This is sad! What are we going to do if
we can't even open files properly? :-)
Please fix this bug as soon as possible.
Submitted On 08-APR-2003
kre
StringBuffer looks like one of the first victims to be hit
with the refactoring stick. For instance, encapsulating all
uses of System.arraycopy and decide about sharing there can
even save some copy operations. Because you know already
what area will be overwritten now, exclude it from the
copying if it looks worthwhile.
There is one case where I would like to see sharing in the
future: when the value.length == size. This is for code that
precomputes the resulting length, and I would expect most
such code benefit from the sharing and unlikely to reuse the
StringBuffer.
Submitted On 22-APR-2003
manu4ever
Why can't this fix be backported to 1.4.1_03?
Submitted On 23-APR-2003
johanges
Not so easy. In Real Life you can't just go and fiddle with people's JVM installations like that. I don't have the rights to redestribute a modified JVM to my customers (and I can't properly sign the jar anyway.)
It really should be in 1.4.1_03 to be of any use. The description "Closed, Fixed" is a bit missleading. Maybe a "Closed, Fixed, To be shipped in n.n.n-nn" would be of more value.
Submitted On 23-APR-2003
jacyg
if you really want it backported, it's not so hard to do it
yourself....just replace the StringBuffer.class in 1.4.1x
with the version in 1.4.0
Submitted On 27-APR-2003
manu4ever
Apparently this bug is fixed in 1.4.1_04, but the 1.4.2 FCS will
almost certainly be out before that.
Let's hope that the first release of 1.4.2 is a bit more quality-
focussed than the first release of 1.4.1.
Submitted On 09-MAY-2003
dserodio
It's fixed in 1.4.1_04, but where can I download it? The
download page only has 1.4.1_02!!!
Submitted On 13-MAY-2003
dserodio
Where can I download this testcase.jar? I'd like to run some
tests on my own...
Submitted On 19-MAY-2003
sharpt
In my opinion, StringBuffer shouldn't be final, which means that it's impossible to subclass it
to correct a problem like this. I have created an alternate implementation, named
ReuseStringBuffer, that avoids the sharing problem, but it cannot be passed to methods that
expect a StringBuffer. Please, when you fix the sharing problem, also remove the final from
StringBuffer. My implementation of setLength does no copy (copy occurs for the toString):
public synchronized void setLength(int newLength) {
if (newLength < 0) {
throw new StringIndexOutOfBoundsException(newLength);
}
if (newLength > value.length) {
expandCapacity(newLength);
}
count = newLength;
}
The boolean <code>shared</code> is needed for StringBuffer
because the String constructor collaborates with StringBuffer to avoid copying
the array unless it is reused after a toString().
Because of this feature, ReuseStringBuffer.setLength(0) reuses the existing value array.
This saves ReuseStringBuffer from having to extend a new array of default capacity
and also avoids assigning unused buffer to the new String created by the toString().
Submitted On 31-MAY-2003
passwordp
Nice to know common sense finally won out.
Submitted On 16-JUN-2003
pigasus1
The fix is listed for 1.4.1_04, but I don't see that build
anywhere. Is it forthcoming? Is it hiding? I too need this fix.
Submitted On 18-JUN-2003
voorde
Instead of replacing the StringBuffer.class in rt.jar would it
work to add an extra jar containing only the 1.4.0 StringBuffer
in the endorsed directory?
Submitted On 23-JUN-2003
gjacobi
When will 1.4.1_04 be available? Like everyone else posting
here, we need this BAD.
Submitted On 24-JUN-2003
mdunstan
We use xml-rpc 1.1 from apache. The following fix worked for
our app.
The solution was posted here:
http://www.mail-archive.com/rpc-dev@xml.apache.org/msg00707.html
Here is the solution we applied:
> I fixed it (somewhat aggressively) by changing the line in
> XmlRpc.java that reads:
>
> parser.parse (new InputSource (is));
> to:
> try
> {
> parser.parse (new InputSource (is));
> }
> finally
> {
> cdata = null;
> }
It also appears JDOM beta 9 includes a fix for the memory leak.
Here are links to the jar files for xmlrpc-1.1 if you don't
want to build it.
www.luxorindustries.com/xmlrpcpatch/xmlrpc-1.1.jar
www.luxorindustries.com/xmlrpcpatch/xmlrpc-1.1-applet.jar
Submitted On 30-JUN-2003
kosmikov
This is marked as fixed in "mantis-rc", so now that 1.4.2
has been released, why isn't it in the list of fixed bugs?
(http://java.sun.com/j2se/1.4.2/fixedbugs/fixedbugs.html).
Surely it qualifies for entry in that list, with having 520
votes!
Submitted On 11-JUL-2003
jgh147
Where is 1.4.1_05 ? I can only see 1.4.1_03 on this site.
Submitted On 23-AUG-2003
atrajano
Has this been fixed on 1.4.2 yet?
Submitted On 19-NOV-2003
OKLeslie2
I'm still having a problem with StringBuffer in version/build
1.4.2-b28 - I submitted a bug explaining this on Nov 18 2003
Submitted On 07-SEP-2006
durai.at.sun
Fair
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|