Challenge - jak najlatwiej/najciekawiej zrobic memory leak w Javie :)

1

Zrobmy maly challenge: jaki znacie najlatwiejsze albo najciekawszy/najfajniejszy sposob na zrobienie w Javie memory leaka?

Update: zalozmy ze jesli autor odpowiedzi nie zaznaczy inaczej przyjmujemy za punt wyjsciowy Jave 8 z domyslnym GC.

1

Najpopularniejszy:
Nie uzycie try-with-resources

Najłatwiejszy:
Dodawanie do hash struktur obiektu ktory nie ma hashCode/equals

Najbardziej paskudny: (bo te wyzej to nawet jetbrains wychwyci, chociaż z niewiadomych mi przyczyn ludzie notorycznie nie patrza na jego hinty)
Dać osobie nie znającej C++ zrobić bindingi do JNI do native C++. (memory leak praktycznie gwarantowany)

1
void leakMemory() throws NoSuchFieldException, IllegalAccessException {
    Field f = Unsafe.class.getDeclaredField("theUnsafe");
    f.setAccessible(true);
    ((Unsafe) f.get(null)).allocateMemory(99999);
}

Co wygrałem? :-)

2

Robisz sobie jakis sprytny cache na mapie i nigdy nic z niego nie usuwasz...
Chyba że mówimy o takich "celowych" z użyciem unsafe czy odwołań do natywnego kodu.

1

tworzenie:
Executors.newFixedThreadPool (lub inej puli)

np podczas wywołań metod.
Pule wątków (oraz i wątki) cały czas sobie istnieją.
Żeby było śmieszniej można pododawać ThreadLocal i nie wiadomo co gdzie jest.

Pule nie są zwalniane i jak dobrze pamiętam są to root obieky dla GC stąd nie są automatycznie odśmiecane nawet jak się im przypisze nulla.

public class PoolLeak {
    private static ThreadLocal<int[]> val = new ThreadLocal<>();
    
    private static void doSomething() {
        ExecutorService execs = Executors.newFixedThreadPool(100);
        for(int i = 0; i < 100; i++) {
            execs.execute(() -> {
                val.set(new int[ 1000]);
            });
        }
        execs = null;
    }
    public static void main(String[] args) throws Exception {
        for(int i = 0; i < 10000000; i++) {
            doSomething();
        }
    }
}

Exception in thread "RMI TCP Connection(idle)" java.lang.OutOfMemoryError: Java heap space
at java.lang.Class.getDeclaredMethods0(Native Method)

4
interface Interfejs {
  int metoda();
}

class BardzoCiężkaKlasa {
  private final int[] tablica = new int[BARDZO_DUŻO];

  Interfejs nibyNiewinnaMetoda() {
    return new Interfejs { // klasa anonimowa ma niejawny wskaźnik do otaczającej klasy, tutaj powodujący tylko i wyłącznie wyciek
      int metoda() {
        return 5;
      }
    }
  }
}

class InnaKlasa {
  private final Interfejs instancja = new BardzoCiężkaKlasa().nibyNiewinnaMetoda(); // tutaj jest wyciek klasy BardzoCiężkaKlasa, która jest tutaj niepotrzebna
}
1

Najprościej i najpewniej to nowy wątek z while(true) w środku i ciężkim polem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1