Suppose I have following code
package memoryleak;
public class MemoryLeak {
public static int size;
static {
size = (int) (Runtime.getRuntime().maxMemory()*0.6);
}
public static void main(String[] args) throws InterruptedException {
{
byte[] data1 = new byte[size];
}
byte[] data2 = new byte[size];
}
}
This code generates OutOfMemoryError. You can make this code work with one variable allocation (which rewrite stack frame used by first array and make array available for garbage collecting). This puzzle explained here.
{
byte[] data1 = new byte[size];
}
int i = 0;
byte[] data2 = new byte[size];
The question is: why following code still doesn't work?
Object o = new Object();
synchronized (o) {
byte[] data1 = new byte[size];
}
int i = 0;
byte[] data2 = new byte[size];
And following works:
Object o = new Object();
synchronized (o) {
byte[] data1 = new byte[size];
}
int i = 0;
synchronized (o) {
byte[] data2 = new byte[size];
}
My bet is that synchronized adds an element to the frame, causing data1 to move up a slot and not get clobbered by i. synchronized needs to unlock the same object that it locked, even if the local/field changes.
The synchronized code would look something like this:
Object $sync = o;
$sync.lock();
try {
byte[] data1 = new byte[size];
} finally {
$sync.unlock();
}
So taking the last sample of code:
Object o = new Object(); // Slot 0.
synchronized (o) { // Slot 1.
byte[] data1 = new byte[size]; // Slot 2.
}
int i = 0; // Slot 1.
synchronized (o) { // Slot 2. (clobbers data1, was slot 1)
byte[] data2 = new byte[size]; // Slot 3.
}
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