2012-06-11 14 views
12

Ostatnio pisałem zajęcia, w których odkryłem, że mogłem zmniejszyć zużycie pamięci instancji o ~ 10 bajtów/element, ale tylko kosztem uczynienia kodu znacznie bardziej złożonym. Zwiększyło to rozmiar skompilowanego pliku .class o ~ 10 KB.Jak oszacować całkowite zużycie pamięci permgowej klasy?

Zakładam, że JVM musi załadować do pamięci plik .class, więc te zmiany nie zapłacą same za siebie, chyba że będzie ich co najmniej 1000. Ale ta arytmetyka nie zadziała, chyba że dodatkowe 10 KB w pliku klasy jest kosztem zwiększonej złożoności kodu.

This Oracle blog sugeruje, że istnieje sporo dodatkowej pamięci uzyskiwanie spożywane przez klasę w PermGen że nie opiera się tylko na pliku .class - na przykład, podejrzewam, że bardziej złożony kod może wymagać więcej pamięci dla optymalizacji metadanych .

Tak, to pytanie ma dwie części:

  • W jaki sposób można zmierzyć rzeczywiste zużycie pamięci PermGen konkretnej klasy? Czy podczas pracy z niektórymi instrumentami lub z narzędziami do profilowania?
  • Czy istnieje sposób na oszacowanie zużycia pamięci przez klasę podczas jej pisania? (Z some background knowledge można oszacować zużycie pamięci instancji klasy jako że je pisać; Zastanawiam się, czy możemy oszacować zużycie pamięci PermGen samej klasie.)

podobne dane dla Dalvik VM Byłbym doceniony, ale głównie koncentruję się na OpenJDK i innych "głównych" maszynach JVM.

+0

Profilowanie może pomóc –

+0

Wymagania dotyczące pamięci będą również zależeć od tego, czy HotSpot ją skompiluje. Kod JITed ma swój własny koszt. –

+0

@JesseWilson: To prawda, ale czy istnieje dobry sposób na oszacowanie tego kosztu? Czy jest to tylko zużycie surowego zestawu, czy też jest dużo dodatkowej księgowości? –

Odpowiedz

4

Jak mogę zmierzyć rzeczywiste zużycie pamięci permen danej klasy? Czy podczas pracy z niektórymi instrumentami lub z narzędziami do profilowania?

Jednym ze sposobów może być załadować klasę pomiaru w innym classloader i korzystania jmap -permstat jak przedstawione w niniejszym blog entry.

Dla każdego obiektu ładowarki klasy, następujące dane są drukowane:

  1. Adres obiektu klasy ładowarki - w migawce gdy narzędzie było uruchomić.
  2. Liczba klas załadowanych (określone przez to ładowarka z metodą (java.lang.ClassLoader.defineClass).
  3. przybliżona liczba bajtów zajmowanych przez meta danych dla wszystkich klas ładowane przez to ładowarka klasy.
  4. Adres nadrzędnego programu ładującego klasy (jeśli istnieje):
  5. Wskazanie "na żywo" lub "martwe" - wskazuje, czy obiekt modułu ładującego będzie w przyszłości gromadzony podczas czyszczenia.
  6. Nazwa klasy tego programu ładującego klasy.
+0

Oooooh. Zbadam to. –

+0

@LouisWasserman - czy udało ci się uzyskać więcej informacji po zbadaniu sprawy? – dimo414

0

To jest odpowiedź na twój drugi punkt; Nie jestem pewien, jak użyteczne byłoby to, ale znalazłem slajdy w prezentacji Building Memory-efficient Java Applications: Practices and Challenges, aby być całkiem pomocne w oszacowaniu rozmiaru i kondycji różnych obiektów Java. Podczas określania wielkości obiektów w 32-bitowych i 64-bitowych maszynach JVM zajmuje się wieloma szczegółami, a także zapewnia wskaźniki, które zwiększają wydajność pamięci.

+0

Rzeczywiście, ta prezentacja motywuje mnie do pisania bardziej złożonych, ale bardziej efektywnych pamięciowo na wdrożenie elementu, ale teraz zastanawiam się, czy mógłbym rzeczywiście pogorszyło problem. ;) –

+0

@LouisWasserman Niekoniecznie gorzej, ale może nieco bardziej skomplikowany. :) –

+0

No cóż ... jeśli w pamięci nie ma nigdy więcej niż 1000 elementów, wydaje się prawdopodobne, że jest gorzej. –

Powiązane problemy