Java memory puzzle

Suppose I have the 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 throws an OutOfMemoryError. You can get this code to work with a single distribution of variables (which overwrite the stack stack used by the first array and make the array available for garbage collection). This puzzle is explained here .

{
    byte[] data1 = new byte[size];
}
int i = 0;
byte[] data2 = new byte[size];

Question: Why is the following code still not working?

Object o = new Object();
synchronized (o) {
    byte[] data1 = new byte[size];
}
int i = 0;
byte[] data2 = new byte[size];

And the following works:

Object o = new Object();
synchronized (o) {
    byte[] data1 = new byte[size];
}
int i = 0;
synchronized (o) {
    byte[] data2 = new byte[size];
}
+3
source share
4 answers

, synchronized , data1 i. synchronized , , /.

synchronized :

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

, :

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.
}
+6

, , (, , ) , data1 = null, ? , , magic.

, , , , .

JVM.

0

. , . , , data1, - , "" , / .

, System.gc(). , 2 . System.gc() - , .

Java . , , . , gc , , , . - , , , - ++ - , . , , , , - , , , .

Update: Confusion. As a couple of other commentators reminded me, the garbage collection cycle obviously starts before jvm throws an OutOfMemory error. However, the behavior is still not deterministic: as this link explains, jvm does not guarantee that all dead objects will be detected in the same garbage collection loop.

0
source

Do you rely on the GC to collect prior to your creation?

Could you do

Object o = new Object();
byte[] data1 = new byte[size];
GC.Collect()
byte[] data2 = new byte[size];
-1
source

Source: https://habr.com/ru/post/1712078/


All Articles