Java记忆难题

Den*_*nov 3 java memory-management

假设我有以下代码

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];
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码生成OutOfMemoryError.您可以使用一个变量分配使这个代码工作(它重写第一个数组使用的堆栈帧,并使make数组可用于垃圾收集).这个难题在这里解释.

{
    byte[] data1 = new byte[size];
}
int i = 0;
byte[] data2 = new byte[size];
Run Code Online (Sandbox Code Playgroud)

问题是:为什么以下代码仍然不起作用?

Object o = new Object();
synchronized (o) {
    byte[] data1 = new byte[size];
}
int i = 0;
byte[] data2 = new byte[size];
Run Code Online (Sandbox Code Playgroud)

以下作品:

Object o = new Object();
synchronized (o) {
    byte[] data1 = new byte[size];
}
int i = 0;
synchronized (o) {
    byte[] data2 = new byte[size];
}
Run Code Online (Sandbox Code Playgroud)

Tom*_*ine 6

我的赌注是synchronized在框架中添加一个元素,导致data1向上移动一个槽而不会受到破坏i.synchronized即使本地/字段发生变化,也需要解锁锁定的同一对象.

synchronized代码会是这个样子:

Object $sync = o;
$sync.lock();
try {
    byte[] data1 = new byte[size];
} finally {
    $sync.unlock();
}
Run Code Online (Sandbox Code Playgroud)

所以采取最后一个代码示例:

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.
}
Run Code Online (Sandbox Code Playgroud)