I am getting a nice SystemOutOfMemory exception 开发者_C百科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
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
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.
What I ended up doing is migrating to x64. This solved my problems.
It is possible that I accually assigned the entire memory space of x86, even though I did not use it all. Migrating to x64 certainly would solve that issue.
精彩评论