Memory usuage is increasing drastically on using StringBUffer???

I am making an RMI call to get the contents of the file in the form of StringBuffer to display that in the text Area.
When i receive the stringBuffer in my UI, its size is nearly 6 times that of the original file. i.e. if the file size is 2mb
StringBuffer size increase to around 12-13 mb. I am creating the buffer like this

public StringBuffer getBuffer()
STringBuffer strFileContents = new StringBuffer();
     File fSgFile = new File(name);
    FileReader fReadder = new FileReader(fSgFile);
    BufferedReader bReader          = new BufferedReader(fReadder);
   String strLine;
    while (  (strLine=bReader.readLine()) != null)
     strFileContents.append( "\n" )
return strFileContents;

Further add to the problem is JTextArea.When I add this StringBuffer to the text Area. Memory usuage again increases

How can I reduce these things.
Who is Participating?
NetminderConnect With a Mentor Commented:
Per recommendation, points refunded and question closed.

EE Admin
INstead of double-buffering in the reader and stringbuffer, can you return the reader instead?
try this:
public StringBuffer getBuffer()
  File fSgFile = new File(name);
  StringBuffer strFileContents = new StringBuffer(fSgFile.length());
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

ugargAuthor Commented:
I tried using the above, but it didn't help, but when i created the stringbuffer with
some lesser initialsize( than the file size), than it slightly reduuces the memory usuage.
but its very marginal improvement
ugargAuthor Commented:
I cann't use Reader as it is not serialized.
Igor BazarnyCommented:

Try to use String instead of StringBuffer. My guess is that StringBuffer is not designed for compactness. BTW, StringBuffer size should be at least twice more than file size, because in typical case one byte corresponds to one 2-byte character. It could be that during serialization StringBuffer reserved size is doubled (it's expected that StringBuffer will increase in size, so code prepares a room for expansion).

Try to clear all references to received String[Buffer] and let garbage collector to clean used memory--JTextArea makes copy of your text.  

Igor Bazarny,
Brainbench MVP for Java 1
bazarny's idea is a good one. When you append to a StringBuffer, it doesn't merely grow by the size of the data appended to it; it grows exponentially! This is why you are finding that a huge amount of data is coming over the wire. The tragedy is that most of it is null characters at the end of the buffer. So you've two solutions:
1. Return a String as bazarny suggests
2. If you want to manipulate the data using the StringBuffer at the other end of the wire, call strFileContents.setLength(strFileContents.length())

Of course, if you don't *need* to use the StringBuffer, then returning the String will represent less overhead.
Appending to a String over and over again is HUGELY innefficient - even worse than the StringBuffer.  I'd stick with the SringBuffer(file.size() * 2);  This shouldn't allocate anything it doesn't need.
Just to clarify my earlier comment, by using a String instead of a StringBuffer, I mean to *return* a string, not to start out with a String and append to it.

In point of fact appending to a String by concatenation is compiled to appending to a StringBuffer and the resulting instructions are not hugely different (see below)

You may as well leave your code as it is but ensure that you only return the information you need by calling strFileContents.setLength(strFileContents.length()) before you return the StringBuffer contents. This will effectively trim the StringBuffer's buffer of the vast number of null characters, returning only the ones you need.


public class StringAppend {

  public String getBufferAsString(String name) throws Exception {
    String wholeFile = null;
    File fSgFile = new File(name);
    FileReader fReadder = new FileReader(fSgFile);
    BufferedReader bReader = new BufferedReader(fReadder);
    String strLine;
    while ((strLine = bReader.readLine()) != null) {
      wholeFile += strLine + "\n";
    return wholeFile;

  public StringBuffer getBuffer(String name) throws Exception {
    StringBuffer strFileContents = new StringBuffer();
    File fSgFile = new File(name);
    FileReader fReadder = new FileReader(fSgFile);
    BufferedReader bReader = new BufferedReader(fReadder);
    String strLine;
    while ((strLine = bReader.readLine()) != null) {
    return strFileContents;



Compiled from
public class StringAppend extends java.lang.Object {
    public StringAppend();
    public java.lang.String getBufferAsString(java.lang.String) throws java.lang.Exception;
    public java.lang.StringBuffer getBuffer(java.lang.String) throws java.lang.Exception;

Method StringAppend()
   0 aload_0
   1 invokespecial #1 <Method java.lang.Object()>
   4 return

Method java.lang.String getBufferAsString(java.lang.String)
   0 aconst_null
   1 astore_2
   2 new #2 <Class>
   5 dup
   6 aload_1
   7 invokespecial #3 <Method>
  10 astore_3
  11 new #4 <Class>
  14 dup
  15 aload_3
  16 invokespecial #5 <Method>
  19 astore 4
  21 new #6 <Class>
  24 dup
  25 aload 4
  27 invokespecial #7 <Method>
  30 astore 5
  32 goto 60
  35 new #8 <Class java.lang.StringBuffer>
  38 dup
  39 invokespecial #9 <Method java.lang.StringBuffer()>
  42 aload_2
  43 invokevirtual #10 <Method java.lang.StringBuffer append(java.lang.String)>
  46 aload 6
  48 invokevirtual #10 <Method java.lang.StringBuffer append(java.lang.String)>
  51 ldc #11 <String "">
  53 invokevirtual #10 <Method java.lang.StringBuffer append(java.lang.String)>
  56 invokevirtual #12 <Method java.lang.String toString()>
  59 astore_2
  60 aload 5
  62 invokevirtual #13 <Method java.lang.String readLine()>
  65 dup
  66 astore 6
  68 ifnonnull 35
  71 aload_2
  72 areturn

Method java.lang.StringBuffer getBuffer(java.lang.String)
   0 new #8 <Class java.lang.StringBuffer>
   3 dup
   4 invokespecial #9 <Method java.lang.StringBuffer()>
   7 astore_2
   8 new #2 <Class>
  11 dup
  12 aload_1
  13 invokespecial #3 <Method>
  16 astore_3
  17 new #4 <Class>
  20 dup
  21 aload_3
  22 invokespecial #5 <Method>
  25 astore 4
  27 new #6 <Class>
  30 dup
  31 aload 4
  33 invokespecial #7 <Method>
  36 astore 5
  38 goto 55
  41 aload_2
  42 aload 6
  44 invokevirtual #10 <Method java.lang.StringBuffer append(java.lang.String)>
  47 pop
  48 aload_2
  49 ldc #11 <String "">
  51 invokevirtual #10 <Method java.lang.StringBuffer append(java.lang.String)>
  54 pop
  55 aload 5
  57 invokevirtual #13 <Method java.lang.String readLine()>
  60 dup
  61 astore 6
  63 ifnonnull 41
  66 aload_2
  67 areturn
Igor BazarnyCommented:

> SringBuffer(file.size() * 2);  
Well, StringBuffer size counted in chars, so there is no need to double it.

CEHJ is right, I didn't mean that String should be used during read operation, but I feel that serializing String would be more efficient than serializing StringBuffer of the same size, especially when StringBuffer allocated a bit of extra space. BTW, 'exponential' growth is not really bad when you think about price of moving content to the new place during reallocation. Doubling size each time current capacity exceeded results in log(size) reallocations (with about size copy operations) and at most 50% of wasted memory.

Igor Bazarny
Have you tried to call System.gc()?
That wouldn't help, Venci75. The problem is the vastly swollen buffer inside the StringBuffer, which wouldn't get garbage-collected.

Experiment with the initial size of the StringBuffer as bazarny suggested and then make the call I suggested before returning.
Look - I was the first one that suggested to use the initial size of the StringBuffer.
But I think that the StringBuffer is not the only problem - there is a lot of garbage generated by the BufferedReader.
So - if ugarg really have to use BufferedReader, instead of reading the file with a buffer, which size won't be increased latter - may be the memory allocated by the BufferedReader should be released.
That wouldn't help, Venci75. The problem is the vastly swollen buffer inside the StringBuffer, which wouldn't get garbage-collected.

Experiment with the initial size of the StringBuffer as bazarny suggested and then make the call I suggested before returning.
Yes, Venci75 you were the first one, sorry! But let's have the questioner do some practical tests before we go any further with theory! (s/he's not even replied yet!)
Igor BazarnyCommented:

If I understand correctly, the problem is on receiving side of RMI call which is not in JVM where all BufferedReader stuff happens. So I was trying to suggest ways to improve serialization performance.

But let's wait for questioner. ugarg, do you have more questions? Did you get your problem solved?

ugargAuthor Commented:
Now instead of passing as StringBuffer I am passing the file contents in the form
of byte array and on the recieving end, i constructed String object from it like

String s = new String( byteArray );

However this  way also memory is sharply rising( ard 6 times as that of actual file size)
and memory usuage increases during string creation only. I couldn't notice much difference by not using String Buffer.

I am creating Byte Array like

         byte data[]
         File file = new File( name );
        data = new byte[ (int)(file.length()) ];
                  (new FileInputStream( file )).read( data )

I will try with whatever CEHJ has suggested         i.e. strFileContents.setLength(strFileContents.length())
and will let u guys know.


ADMINISTRATION WILL BE CONTACTING YOU SHORTLY.  Moderators Computer101 or Netminder will return to finalize these if they are still open in 14 days.  Experts, please post closing recommendations before that time.

Below are your open questions as of today.  Questions which have been inactive for 21 days or longer are considered to be abandoned and for those, your options are:
1. Accept a Comment As Answer (use the button next to the Expert's name).
2. Close the question if the information was not useful to you, but may help others. You must tell the participants why you wish to do this, and allow for Expert response.  This choice will include a refund to you, and will move this question to our PAQ (Previously Asked Question) database.  If you found information outside this question thread, please add it.
3. Ask Community Support to help split points between participating experts, or just comment here with details and we'll respond with the process.
4. Delete the question (if it has no potential value for others).
   --> Post comments for expert of your intention to delete and why
   --> YOU CANNOT DELETE A QUESTION with comments; special handling by a Moderator is required.

For special handling needs, please post a zero point question in the link below and include the URL (question QID/link) that it regards with details.
Please click this link for Help Desk, Guidelines/Member Agreement and the Question/Answer process.

Click you Member Profile to view your question history and please keep them updated. If you are a KnowledgePro user, use the Power Search option to find them.  

Questions which are LOCKED with a Proposed Answer but do not help you, should be rejected with comments added.  When you grade the question less than an A, please comment as to why.  This helps all involved, as well as others who may access this item in the future.  PLEASE DO NOT AWARD POINTS TO ME.

To view your open questions, please click the following link(s) and keep them all current with updates.

*****  E X P E R T S    P L E A S E  ******  Leave your closing recommendations if this item.  If you are interested in the cleanup effort, please click this link 
POINTS FOR EXPERTS awaiting comments are listed here ->
Moderators will finalize this question if in @14 days Asker has not responded.  This will be moved to the PAQ (Previously Asked Questions) at zero points, deleted or awarded.
Thanks everyone.
Moderator @ Experts Exchange
To be more precise, in one of my earlier posts, I used the word 'exponentially' to describe how the StringBuffer expands when allocation is insufficient. This is not true in the mathematical sense, as doubling anything is not applying an exponential function!
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:
PAQ'd and pts refunded
Please leave any comments here within the next seven days.
EE Cleanup Volunteer
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.