2015-05-14 8 views
5

Java nie powinna mieć przecieków pamięci, ale nadal jest możliwa. Kiedy mój program ma wyciek pamięci, mogę to naprawić (mam nadzieję). Ale kiedy mają jakieś paczki stron trzecich, co mogę zrobić? Praktycznie nic oprócz tego, że nie korzystasz z tego pakietu.Piaskownica do pamięci

Czy istnieje inne rozwiązanie? Podoba mi się pomysł piaskownicy. Możesz robić, co chcesz w danym obszarze, a ty "fizycznie" nie masz możliwości przeszkadzania innym poza twoim pudełkiem. Czy istnieje sposób na stworzenie takiej piaskownicy dla użycia pamięci w Javie? Imagine = utwórz piaskownicę do użycia pamięci, pozwól, aby jakaś paczka robiła cokolwiek robi, weź wyniki i usuń tę piaskownicę z resztkami śmieci tutaj! Brak komplikacji z GC, brak czyszczenia lub dyspozycji pamięci. Po prostu usuń i zapomnij o tym.

Czy można to zrobić?

Odpowiedz

1

Najlepszym sposobem jest uruchomienie kolejnej maszyny JVM, komunikowanie się z nią za pomocą gniazda (na przykład) i zabicie maszyny JVM po jej zakończeniu.

Interesujące będzie omówienie, czy możemy przeprowadzić piaskownicę w tej samej maszynie JVM.

Po zakończeniu korzystania z biblioteki trzeciej strony, a użytkownik nie odwołuje się już do żadnych obiektów z tej biblioteki, jakie mogą być śmieci, które wciąż trwają?

  1. swoich klasach - nawet jeśli nie są referening każdy z nich, jeśli są one ładowane przez tego samego classloader jak kod, te zajęcia będą się utrzymywać. I ich pola statyczne mogły odwoływać się więcej powolną danych, i tak dalej

  2. ThreadLocal - to mogło ustawić kilka wątków zmienne lokalne, a nie czyścić je

  3. wątek - to mogło zrodził pewne wątki, które nadal istnieją

  4. W niektórych globalnych miejscach - np. System.setProperty() - pozostanie tam.

Generalnie jest to prawdopodobnie trudne.

Możemy jednak użyć oddzielnego programu ładującego klasy i osobnego wątku do wykonania biblioteki innej firmy, a ta strategia może w większości przypadków prawdopodobnie wyładować wszystkie pakiety generowane przez osobę trzecią.

Czy istnieją narzędzia do tego? Nie mam zbyt dużej wiedzy na ten temat. Mam pewne doświadczenie z wdrażaniem hot reloadable server i mam kilka klas narzędziowych, które mogą być użyte do tego celu. Na przykład

// wrap 3rd party code, expose it as some java.*.* interface 
public class MyWrapper implements Callable<String> 
{ 
    @Override 
    public String call() 
    { 
     return ThirdParty.query(..); 
    } 
} 



HotReloader hot = new HotReloader(); 
Callable<String> func = (Callable<String>)hot.getAppInstance("pkg.MyWrapper"); 
String result = func.call(); 
// then dereference `hot` and `func` 

zobaczyć HotReloader

+0

że to dobry pomysł, ale trochę drogie. Czy możesz sobie wyobrazić, aby uruchomić nową maszynę JVM dla każdego żądania bazy danych? Byłem kiedyś na konferencji JavaOne na prezentacji Plumbr "Założę się, że masz wyciek pamięci" i kilka ich przykładów dotyczyło wycieku pamięci w standardowych sterownikach baz danych. To był MySql, jeśli się nie mylę. –

+0

Można użyć ClassLoaders do izolowania klas problemów. Następnie, aby wyczyścić pamięć używaną przez bibliotekę, usuwa się wszystkie odniesienia do jej klas i programu ładującego. Można również użyć oddzielnej grupy wątków do izolowania wątków bibliotek, co pozwala łatwo je zabić. –

+0

@IzoldTytykalo - możesz użyć jednej JVM dla 2 zapytań do bazy danych :) lub więcej. – ZhongYu

Powiązane problemy