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
synchronizedadds an element to the frame, causingdata1to move up a slot and not get clobbered byi.synchronizedneeds to unlock the same object that it locked, even if the local/field changes.The
synchronizedcode would look something like this:So taking the last sample of code: