Garbage Collection - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



Java

Garbage Collection

java

3. června 2002, 00.00 | Garbage Collection jako automatizovaná uklízečka vaší paměti. Co možné nevíte je, že ho můžete do jisté míry ovlivňovat, stejně
jako reálnou uklízečku

Java se svým Garbage Collection se do jisté míry podobá Delphi1. Především v tom, ohledu, že Java resp. Garbage Collection sám po programátorovi ruší jednotlivé proměnné, které již nebude potřebovat.

Tento způsob je vcelku nezvyklý pro céčkaře, kteří jsou naučení, že si musí sami po sobě uklidit. Java však dává programátorovi možnost svobodně se rozhodnout. Existují totiž způsoby jakými lze Garbage Collection ovládat či ho přímět k některým krokům.

Dříve než se na ně podíváme, stálo by za povšimnutí, jakým způsobem vlastní Garbage Collection pracuje.

V průběhu programování si vytváříme různá proměnné či objekty, které nás po jisté době vůbec nezajímají a je tedy na Garbage Collection, aby je za nás odstranil. Kdyby tak Garbage Collector2 průběžně nečinil, hrozilo by nám nebezpečí, že by se náš program po jisté době zhroutil, protože by zabral veškerou dostupnou paměť3.

Místa v paměti, která zabírají proměnné, které již programátor nepoužije se v terminologie nazývají jako memory leaks a je na Garbage Collectoru, aby je našel a odstranil.

Z toho všeho by se mohlo zdát, že se Garbage Collector vcelku často spouští a provádí kontrolu paměti. Jak si ukážeme, později opak je pravdou. Garbage Collector má dost vysoké požadavky a tak podstatně zpomaluje běh programu, proto se jeho spouštění oddaluje až do nejzašší možné doby. To je částečně jeden z důvodů, proč je Java tak náročná na paměť.

Na začátku jsem říkal, že programátor v Javě má možnost sám pro sobě uklízet. To lze provádět přiřazením hodnoty null danému objektu. Obzvláště se to hodí u rozsáhlých objektů či proměnných např. polí. Tímto způsobem také do jisté míry ulehčujete, tedy zrychlujete, práci Garbage Collectoru.

     int[] Stat = new  int[1000];
// nějaké operace
     Stat = null  ;

Z příkladu je krásně vidět jakým způsobem nastavit hodnotu null. Bohužel tímto způsobem nelze označit konstanty.

Toto je moc hezké, ale nevede to zcela k očekávanému výsledku. Označili jsem sice Garbage Collectoru to, co se má odstranit, ale díky nízké prioritě threadu, který ho spouští, se data neodstraní ihned. Tento stav lze napravit okamžitým provedení Garbage Collectoru 4

     System.gc();

Někdy se však můžete dostat k zcela odlišnému problému, rychlosti. Bude Vám tedy zcela ukradená velikost zabrané paměti. To můžeme řešit zakázáním Garbage Collectoru. Běh programu se sice zrychlí, ale nezapomeňte, že z paměti nebude odstraněno jediné písmenko!

java -Xnoclassgc gc HelloWorld

Poznámka: ve starší verzi se místo parametru Xnoclassgc používalo noasynch.

Práce s pamětí

Chci-li vytvořit něco velkého, jak mám vědět, zda volat či nevolat Garbage Collector, který by mi získal více paměti?

Je to jednoduché stačí se pouze zeptat kolik je paměti momentálně volné a kolik ji potřebujete. Podle toho se rozhodnout zda ho volat či nikoliv.

     Runtime rt_info = Runtime.getRuntime();
     System.out.println("Free memory: " +rt_info.freeMemory());
     if  (rt_info.freeMemory() < neededMemory)
          System.gc();
     BigObject BO = new  BigObject();

Tento příklad názorně zobrazuje řešení. Ovšem negarantuje, že po volání Garbage Collectoru opravdu bude dostatek paměti pro daný objekt. Té totiž může být málo i z jiných důvodů — zabírají je ostatní programy, celková paměť není tak velká apod.

Obě se dají zjistit za pomocí zjištění celkové paměti a volné paměti.

     Runtime rt_info = Runtime.getRuntime();
     System.out.println("Total memory: " +rt_info.totalMemory());
     if  (rt_info.totalMemory() < neededMemory) {
          System.err.println("Absolutni nedostatek pameti");
          return  ;
     } else  if  (rt_info.freeMemory() < neededMemory) {
               System.gc();
               if  (rt_info.freeMemory() < neededMemory) {
                    System.err.println("Ostatni programy zabiraji prilis pameti");
                    return  ;
               } else  { System.out.println("Pamet byla v dostatecne mire uvolnena"); }
          } else  { System.out.println("Neni nutno uvolnovat pamet"); }
      BigObject BO = new  BigObject();

SizeOf

V datových typech jsem se zmínil o tom, že v Javě není možné používat operátor sizeof() pro zjištění velikosti proměnných či objektů. Pozorný čtenář si ale všiml, že v příkladech používám proměnou neededMemory, která se má vázat k objektu BigObject (fiktivní).

Jak jsem ji tedy zjistil? Velikost lze zjistit přes již zmíněnou metodu freeMemory, i když musím dodat, že výsledek nemusí být přesný. Může být ovlivněn Garbage Collectorem tohoto programu — lze potlačit, ale také ostatními programy, jejich počet však lze také minimalizovat, jsou tu však i další vlivy se kterými se těžko něco udělá.

// soubor sizeof.java
public  class  sizeof {
     public  static  void  main(String  args[]) {
          long neededMemory = 0;
          long actMemory, diff = 0;
          Runtime rt_info = Runtime.getRuntime();
          for  (int i = 0; i < 9; i++) {
               actMemory = rt_info.freeMemory();
// create Object
               String  [] S = new  String  [1000];
...
               System.out.println(rt_info.freeMemory() -actMemory);
          }
     }
}

Heap

U Javy si však můžete ještě hrát s přidělováním paměti při jejím spuštění. K tomu slouží opět speciální parametry např. Xms<size>, Xmx<size>Xss<size>.

Tyhle ty parametry se asi budou hodit v případě, že potřebujete z nějakého důvodu limitovat přidělovanou paměť Javě.

Pomocí Xms<size> můžete nastavit počáteční velikost heapu Javy. Dále pomocí Xmx<size> lze zase nastavit maximální velikost heapu Javy. A jako poslední lze nastavit velikost stacku Javy.

java -Xmx9000000 neco

1. – Pro rejpali: vím, že se liší, ale výsledek je téměř stejný nepoužívané proměné se odstraňují. Něříkám jak!
2. – Mluvím-li o Garbage Collection mám na mysli obecný proces odstraňování objektů. Při spuštění programu je fyzicky realizován krz Garbage Collector.
3. – nutně se nemusí jednat o celou operační paměť počítače
4. – Nezapomeňte na to, že Garbage Collector bere dost výkon, takže ho nevolejte když to není nutné :o(

Tématické zařazení:

 » Rubriky  » Java  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: