And minior collection every 1 minute reducing this values to 2,000,000 and 400,000,000 accordingly.

I use a lot StringBuilder to generate some complex HTML code it would be difficult to make in JSP and put it as value of hutputText (with escape=false). Can it be the problem? Anyway right now minor collection happening every 1 minute but traffic is still very low. I have assigned 8gb to xmx and xms and I think it's too much (major collection takes around 8-10 seconds during heavy traffic hours every 20 mins).

Exactly how are you creating a StringBuilder? According to the javadocs, the no args constructor gives only 16 characters - that initial char[] will be abandoned quickly if you are building big Strings. The String arg constructor starts with the string length + 16 - also likely to be abandoned early.

If this was my problem I would use the StringBuilder( someInt ) with a realistic estimate of the eventual length needed, thus avoiding all the intermediate char[] creation.

The automatic capacity increase just doubles the char[] size - see AbstractStringBuilder

Michal Glowacki
Ranch Hand

Joined: Mar 14, 2006
Posts: 114

posted Aug 30, 2011 07:38:32

0

I think I do it hard way, but it is difficult for me to change it as the size depends on the numbers of rows returned from database:

I'd handle this using the Google Guava collections methods and objects. With them, you dont' have to read all the rows from the DBMS into memory, you can use an Iterable and access each row inside the loop where you need the values. (You can do it without Guava, but it has so many other features that I normally start thinking of using it.) Guava is free, open source, available from Google, well supported, etc.

Its never a good idea to read in thousands of rows before you process the first one.

William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12890

5

posted Aug 30, 2011 14:24:35

0

If this was my problem I would use new StringBuilder( 10000 ) or maybe 20000 - more than needed probably but think of all the extra char[] that would not be created, and there would only be one char[] to be garbage collected.

A further GC consideration is that all those little char[] can leave your memory fragmented.

William Brogden wrote:A further GC consideration is that all those little char[] can leave your memory fragmented.

Not really. Modern garbage collectors actually compact the heap. (This makes memory allocation in Java lightning fast, no inspection of available memory linked-lists, just updates to the memory pointer. It can even make up for the performance overhead garbage collectors produce.)

If this was my problem I would use new StringBuilder( 10000 ) or maybe 20000 - more than needed probably but think of all the extra char[] that would not be created, and there would only be one char[] to be garbage collected.

I'd suggest to try to obtain a distribution of sizes your code produces in real environment. Then looking at that, you might come up with sensible initial capacity that would suffice in large number of cases.

Michal Glowacki
Ranch Hand

Joined: Mar 14, 2006
Posts: 114

posted Sep 26, 2011 03:34:03

0

I am still struggling with this problem. I have made some screenshots, when CPUs are working 50-90% and the traffic is low. JBoss process is more than 9GB at this moment. Here are my jvm settings:

Michal
I am not an expert with performance but here are my thouhghts.
The StringBuilder initialization should certainly help.
Apart from that the screen shots show lots of Object[] and String . Have you inspected the stack trace of those Objects ?
Also how about caching certain strings that are repeatedly used ? like the HTML elements .

I second the suggestion to set the initialCapacity on the StringBuilder. That should give you quite a boost.

Another suggestion:-
You might want to try pooling the StringBuilder so you don't create an instance for each request. This will reduce the number of char[] that the GC has to manage. Basically, the only time a char[] will be collected is when the StringBuilder is evicted from the pool, and if you tune the pool right, that should happen only when the load is low. Also, another advantage is that having a pool allows you to degrade gracefully. If the pool is maxed out, you can either make the request wait till instances are available or show a "Server busy" error message. Although either way is not the most desirable, it's much better than overallocation which is going to adversely affect all requests. Most probably you have a limit on JBoss's thread pool anyways. Depending on how much memory is used per request, you might be able to set the maxsize of StringBuilder pool = maxsize of JBoss thread pool

When you passivatethe StringBuilder the pool, call setLength(0). That should clear the array without deallocating it. setLength isn't cheap. So, there will be an overhead. You'll need to benchmark it to measure the impact.

ETA: Are you sure you can't change your implementation to build the HTML in JSP. I get the feeling that you are running into problems that JBoss has already solved. You might be reinventing the wheel a bit here.