Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve stringBuilder fragmentation?

I am getting a nice SystemOutOfMemory exception in my StringBuilders. It is not due to lack of ram, thus I believe it is memory fragmentation.

I have ~200 StringBuiler objects. All of these are reused regularly (with strBldr.clear()). This seems to cause my system to fragment the memory pretty bad. How can I solve this?

Thanks :)

EDIT:

Here are some data:

Max recorded size of input& stringBuilder: 4 146 698.

Avarage re-initiated stringBuilders/second: >120 (possibly >>120)

Length of input @ first error: 16 972 (string)

StringBuilder length @ first error: 16

Count of times a new stringBuilder had been made @ first error: ~32500

Total ram usage @ first error 637 448K

like image 686
Automatico Avatar asked Feb 24 '23 05:02

Automatico


2 Answers

I agree, most likely you are not running out of memory but into fragmentation.

You have to get acquainted with fragmentation and the Large Object heap (LOH).

You don't provide any details so I can only give some very broad advice:

  • try to estimate how large your strings will be and use the Capacity parameter for a new SB
  • round up (really) those sizes to multiples of some number. This promotes re-use.
  • only use Clear() when you expect the new contents to be almost the same size as the old, growing it is what kills you.

Edit

Max recorded size of input& stringBuilder: 4 146 698.

  • Make sure there are no intermediates needed with a greater size, then
  • Create all StringBuilders like sb1 = new StringBuilder(4200000);
  • Don't try to re-use them (too much / at all)
  • Don't keep them around too long
like image 116
Henk Holterman Avatar answered Feb 26 '23 19:02

Henk Holterman


You should not reuse a StringBuilder like that, just create a new one as needed.

When you call Clear on a StringBuilder it will not release all the memory that it used, it will only reset the used size to zero. It will still have the same large buffer, and repeated use of the StringBuilder only means that the buffer will be as large as it ever needed to be, and never shrink.

Also, keeping the StringBuilder objects for reuse means that they survice garbage collections and move on to the next generation heap. Those are collected less frequently, so they are more likely to be sensetive to memory fragmentation.

like image 39
Guffa Avatar answered Feb 26 '23 18:02

Guffa