After analyzing a heap dump I found that there were some 30MB strings allocated (single string of 30 MB).
Is there a way to set a break point while debugging the application so I can find the code which allocates these huge strings?
Since thousands of strings are allocated during application run it isn't possible just putting a break point on each string allocation.
I believe conditional break point will be too slow as well.
If possible I would want to exam those strings content to understand the origin of these allocation.
For example they may be a result of a web service call which usually is called with small amount of data but in rare cases with huge input (which are the cases I want to find).
Although you explicitly asked for a debug session, I assume that this was mainly an attempt to solve the actual problem: Large strings are allocated, and you don't know where this happens.
The allocations can be traced with jVisualVM. You can start jVisualVM and your program, and connect the jVisualVM to your program.
If this does not suit your needs, I can delete this answer. Otherwise, here's how you can do it:
In the "Profiler" tab you can check the "Settings" checkbox in the upper right, and select the "Memory Settings" tab. There you can set the "Record allocation stack traces" checkbox:
Then, after pressing the "Memory" button at the top, the profiler will collect the information about the string allocations. After the application has exited (or after a snapshot has been taken), you can examine the recorded stack traces to find the method that allocates the large string - in this example, method4
:
Copy the source code of java.lang.String
from JDK sources to your
project
Create a method in your String.java like below (count is an existing instance variable of java.lang.String
)
private void checkSize(){
if(count>1000000) //1MB
System.out.println(count);
}
Edit java.lang.String
to call this method checkSize()
at the end of every constructor
Add breakpoint at the line System.out.println(count);
Add the new java.lang.String
to bootstrap classpath
This breakpoint will break only when a String of size > 1MB gets created
I'd try the conditional breakpoint, even if it meant leaving the app running for a day or two. At least then you can get on with something else while it is running. And any other solution is likely to take a day or two to implement anyway.
Failing that, you could using AspectJ to add pointcut into the String constructors and use that to log a message, throw an exception etc. This is basically the same as a conditional breakpoint but should run more quickly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With