0

Following an OutOfMemoryError I processed the resultant heapdumps through IBM Support Assistant's 64bit memory analyzer ( J9 VM running on Websphere 7.0.23)

Several leak candidates were listed ( all system classloader related ) however one of these appears to indicate that a char[] initialised with a value of 256 in StringBuffer actually contains 77 million null characters.

The resultant heapdump analysis from the Support Assistant shows a char[77418987] @ 0xc32*** \u0000\u0000\u0000.......

this is referenced by StringBuffer -> PatternLayout -> TimeAndSizeRollingAppender

The retained heap checks out, 2 bytes for each char and 18 for the array itself for a total of 150+ Mbs.

Log4j version is 1.2.16 and we use the simonsite TimeAndSizeRollingAppender ( though I would like to remove this dependency ).

Could this be a false positive from Support Assistant or is there some way in which a char[256] can become a char[77000000+] on the heap?

Chaffers
  • 176
  • 9
  • 1
    "actually contains 77 million null objects" - no, it contains 77 million U+0000 characters. There's no such thing as a "null object". It's worth being precise in your use of terminology. It sounds like a bug in whatever is creating the `StringBuffer` - can you link to the relevant code? – Jon Skeet Feb 27 '14 at 11:30
  • Edited. Screenshot available here http://s1026.photobucket.com/user/Spinflight/media/charstackoverflow_zpsa176f1f5.png.html – Chaffers Feb 27 '14 at 11:34
  • StringBuffer appears to be created by log4j PatternLayout.java. – Chaffers Feb 27 '14 at 11:36
  • 'code' this.BUF_SIZE = 256; /* 410 */ this.MAX_CAPACITY = 1024; /* */ /* 414 */ this.sbuf = new StringBuffer(256); 'code' – Chaffers Feb 27 '14 at 11:37
  • Well the `StringBuffer` is appended at line 506: `c.format(sbuf, event);`. Do you have a full stack trace? Perhaps you're trying to log something which was *enormous*? – Jon Skeet Feb 27 '14 at 11:42
  • @Chaffers, to correctly use the code mini-Markdown, replace the word **code** between the single quotes (') with the code you wish to show. – Eric Feb 27 '14 at 11:44
  • Will do munyul.. Hmmm yes, looks as though 'MAX_CAPACITY' is unused and the StringBuffer's char[] just grows... – Chaffers Feb 27 '14 at 11:58

1 Answers1

2

By default, WebSphere generates a PHD file in response to an OOM event. One thing you need to be aware of is that these dumps contain information about the objects in the heap and their references, but not the actual data stored in attributes and arrays (of primitive types). That's why the memory analyzer only shows zeros. To get more information about the root cause, you should configure your WebSphere to create a system dump. That will allow you to see the data in the array and should give you a hint about what is happening.

The following link explains how to do this:

http://pic.dhe.ibm.com/infocenter/isa/v4r1m0/topic/com.ibm.java.diagnostics.memory.analyzer.doc/producing.html

For the 256 vs. 77000000+ question: 256 is only the initial capacity of the StringBuffer. It grows automatically as needed when data is appended.

Andreas Veithen
  • 8,868
  • 3
  • 25
  • 28
  • 1
    Thank you andreas, that explains the nulls. As for the question itself, complete misunderstanding of the commonly used StringBuffer class and what it does I'm afraid. – Chaffers Mar 06 '14 at 14:09