Re: Problem with StringBuffer

2000-04-01 Thread Tatu Saloranta


Wolfgang Muees wrote:
> 
> Am Mit, 29 Mär 2000 schrieb Tatu Saloranta:
> > I finally found out the reason for 'memory leak' on my Java program,
> > and the culprit in this case was StringBuffer - implementation.
> >
...
> > (or length of the buffer via setLength()). The problem here is that
> > as soon as I encounter a long token (~4000 chars in this case),
> > _all_ tokens after that will use up the same 4k memory
> 
> The right solution for this problem is IMO: don't reuse StringBuffer.
> It is designed primary as an input buffer for a single string.

I think I disagree here; at least if there's no other class for similar
purpose. I am interested in optimizing Java-programs, and in general,
one of the most efficient optimizations is to recycle objects. Object
creation is not a cheap operation. Especially in this case, where
StringBuffer does allocate a character array, it means there are at
least 2 memory allocations and other initialization code. If the
array truncation can be done when the array is being copied (during
destringify() or whatever the method was), it won't add a new array
allocation.

An alternative would then be a replacement for StringBuffer that would
be designed to be reusable. Not a huge task, and perhaps it might be
worth the effort, at least in my case.

In any case, I guess it all depends on how difficult it is to alleviate
the problem. The fundamental problem I guess is that although it is
String() instance that should really do the truncation (so as not to
use huge char array for storing just few characters), it is StringBuffer
that is responsible for doing that; String just takes the given array
and length, and after that passively just uses what it got. JDK-fix
notes that, and alleviates the problem so that none of the resulting
strings have higher than 100% overhead. :-)

In any case I think it's an oversight in developers of Java base
classes;
if they had known the problem, there would be something in description
of StringBuffer - class to indicate it's not supposed to be reused.

-+ Tatu +-



Re: StringBuffer patch.

2000-04-01 Thread Archie Cobbs


Mo DeJong writes:
> Between revisions 1.11 and 1.12 of
> libraries/javalib/java/lang/StringBuffer.java
> the access of the StringBuffer.ensureCapacity(int)V method was changed
> from public to private.

Oops, my fault -- should be fixed now.

-Archie

___
Archie Cobbs   *   Whistle Communications, Inc.  *   http://www.whistle.com



Re: Problem with StringBuffer

2000-04-01 Thread Archie Cobbs


Wolfgang Muees writes:
> > I finally found out the reason for 'memory leak' on my Java program,
> > and the culprit in this case was StringBuffer - implementation.
> > 
> > I have a lexer (made with JFLex), that uses StringBuffer for
> > constructing
> > the strings for certain tokens. The StringBuffer is reused so that each
> > time a new such token is getting creted, StringBuffer.setLength(0) is
> > called. However, in Kaffe's implementation at least, the actual length
> > of the buffer is not changed. This wouldn't be a big problem in itself,
> > as there's just one StringBuffer instance... But, alas, as Strings &
> > StringBuffers are optimized so that when new String(StringBuffer) is
> > called, the character array is actually shared between the string
> > and string buffer, until the StringBuffer needs to change the data
> > (or length of the buffer via setLength()). The problem here is that
> > as soon as I encounter a long token (~4000 chars in this case),
> > _all_ tokens after that will use up the same 4k memory
> 
> The right solution for this problem is IMO: don't reuse StringBuffer.
> It is designed primary as an input buffer for a single string.

Yesterday I checked in some changes which should alleviate this
problem nonetheless.. please give them a try and let us know if
they help.

-Archie

___
Archie Cobbs   *   Whistle Communications, Inc.  *   http://www.whistle.com



StringBuffer patch.

2000-04-01 Thread Mo DeJong


Hello.

Between revisions 1.11 and 1.12 of
libraries/javalib/java/lang/StringBuffer.java
the access of the StringBuffer.ensureCapacity(int)V method was changed
from public to private.

+private void ensureCapacity(int minCapacity) {
+   if (minCapacity <= 0)
+   return;
+   synchronized (this) {
+   ensureCapacity(minCapacity, false);
+   }
 }
 
-public synchronized void ensureCapacity ( int minimumCapacity ) {
-   intn;
-   char[] oldBuffer;
+// This method assumes synchronization



This was an error, the method should be public. The change generated
errors like the following in my code.

l:/home/mo/project/kaffe/install/share/kaffe/Klasses.jar \
/home/mo/bin/jikes -g \
-d /home/mo/project/tcljava/unix/Kaffe/jacl \
tcl/lang/*.java sunlabs/brazil/util/regexp/*.java

Found 6 semantic errors compiling "tcl/lang/FileUtil.java":

89. absBuf.ensureCapacity(absBuf.length() + path.length());
<>
*** Error: Method "void ensureCapacity(int $1);" in class
"java/lang/StringBuffer" has private access. Therefore, it is not
accessible in class "tcl/lang/FileUtil".




The following patch fixes the problem.


Sat Apr  1 08:00:00 PST 2000  Mo DeJong <[EMAIL PROTECTED]>

* libraries/javalib/java/lang/StringBuffer.java: fixed
problem with ensureCapacity() method, it was accidently
changed to private access when it should have been public.



Index: libraries/javalib/java/lang/StringBuffer.java
===
RCS file: /cvs/kaffe/kaffe/libraries/javalib/java/lang/StringBuffer.java,v
retrieving revision 1.12
diff -u -r1.12 StringBuffer.java
--- libraries/javalib/java/lang/StringBuffer.java   2000/03/31
23:29:591.12
+++ libraries/javalib/java/lang/StringBuffer.java   2000/04/01
12:43:13
@@ -104,7 +104,7 @@
}
 }
 
-private void ensureCapacity(int minCapacity) {
+public void ensureCapacity(int minCapacity) {
if (minCapacity <= 0)
return;
synchronized (this) {



Mo Dejong
Red Hat Inc.