Frage zum GC

jeipack

Erfahrenes Mitglied
Hi
Ich habe eine kleine Frage zur genauen Funktionsweise zum GC.
Und zwar angenommen ich habe eine Applikation die 256mb zugewiesen bekommen hat. Nun braucht irgend ein Teil dieser Applikation sagen wir 100mb. Wenn dieser Teil nun nicht mehr referenziert ist wird er ja vom GC wieder aufgeräumt. Wie funktioniert dieses Aufräumen nun genau?
Der Platz wird wieder freigegeben. Wird er nur für die Applikation intern wieder freigegeben, oder wird er sozusagen ans System zurückgegeben? Weil immer gleich ans System zurückgeben (free) um dann ein paar Milisec später wieder Platz anzufordern (allocate) wäre ja auch ein bisschen overhead.
Hoffe mir kann dass jemand ein wenig verständlicher machen!

Gruss
jeipack
 
AFAIK:

Der GC läuft einerseits zyklisch und wenn der Heap Speicher ausgeht. Dabei entweder für den ganzen Speicherbereich oder für einen Speicherbereich.

Soviel ich weiß wird es nur für die Java Applikation intern wieder freigegeben. Ich glaube nur bei Speichergrößen im GB Bereich wird auch Speicher wieder ans System zurückgegeben.

Ansonsten kannst du den Heap Verbrauch und die Funktionsweise des GC auch in der JConsole verfolgen( enthalten im JDK)
 
Hi
Vielen Dank Anime & Tom.
@Tom, weisst du denn ob es nun so eine Funktion ala System.release() aus deinem ersten Link gibt?

Dann aus dem zweiten Link:
Sun's JVM only allocates memory, deallocates memory only after a specific ratio between internal memory needs and allocated memory drops beneath a (tunable) value. The JVM starts with the amount specified in -Xms and can be extended up to the amount specified in -Xmx. I'm not sure what the defaults are. Whenever the JVM needs more memory (new objects / primitives / arrays) it allocates an entire chunk from the OS. However, when the need subsides (a momentary need, see 2 as well) it doesn't deallocates the memory back the the OS immediately, but keeps it to itself until that ratio has been reached. I was once told that JRockit behaves better, but I can't verify it.
Kannst du mir hier bei der Übersetzung und Interpretation helfen?
Also sobald eine gewisse Ratio von verwendetem Speicher und reserviertem Speicher unterschritten wird wird Speicher wieder freigegeben, korekt? Hat diese Ratio einen bestimmten Namen oder kennst du den Defaultwert? Angenommen ich habe eine App die 1024MB allocated hat, bei wie viel internem Gebrauch wird dann Speicher wieder frei gegeben?
Wenn Anime sagt dass das erst ab grossem Speicherverbrauch (GB) beginnt, muss die Ratio ja recht hoch (oder tief, je nachdem wie man es ansieht;) ) sein.


Gruss
jeipack
 
Hallo,

hmmm, ich weis selbst nicht wie man das kontrollieren kann. Ich weis nur das auch Prozess-Speicher von JVM wieder freigegeben werden kann.

*Vielleicht* lässt sich das hier rüber steuern:
-XX:MaxHeapFreeRatio=70
http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp#PerformanceTuning

Bei den JVM/GC Options tut sich von Version zu Version so viel, dass ich das selbst nicht mehr ganz durchblicke. Im Endeffekt muss man das Verhalten jedesmal wieder in der Doku nachlesen. Zum Teil geben die JVM Options auch nur Empfehlungen an die JVM Hersteller an und die müssen sich nicht notwenigerweise daran halten...

Versuchs doch mal selbst: (Kannst auch im Windows Taskmanager zuschauen)
Java:
package de.tutorials;

import java.lang.management.ManagementFactory;
import java.util.concurrent.TimeUnit;

import sun.misc.Version;

public class ReleaseSystemMemoryExample {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {

		Version.print();
		System.out.println(System.getProperty("os.name") + " " + System.getProperty("os.version"));

		printMemoryStatus();
		System.out.println("Consume memory");
		byte[][] data = new byte[60][1024 * 1024];

		printMemoryStatus();
		TimeUnit.SECONDS.sleep(2);
		System.out.println("Free memory");
		for (int i = 0; i < data.length; i++) {
			data[i] = null;
			System.gc();
			TimeUnit.MILLISECONDS.sleep(500);
			printMemoryStatus();
		}
	}

	private static void printMemoryStatus() {
		System.out.printf("JVM Heap: %s Total Process: %s\n", 
				ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed()
				, Runtime.getRuntime().totalMemory()
				);
	}
}

Ausgabe:
Code:
java version "1.6.0_13"
Java(TM) SE Runtime Environment (build 1.6.0_13-b03)
Java HotSpot(TM) Client VM (build 11.3-b02, mixed mode, sharing)
Windows Vista 6.0
JVM Heap: 227416 Total Process: 5177344
Consume memory
JVM Heap: 63065296 Total Process: 79220736
Free memory
JVM Heap: 63065472 Total Process: 113037312
JVM Heap: 60968288 Total Process: 113037312
JVM Heap: 60968288 Total Process: 113037312
JVM Heap: 60968288 Total Process: 113037312
JVM Heap: 60968288 Total Process: 113037312
JVM Heap: 56773920 Total Process: 113037312
JVM Heap: 56773920 Total Process: 113037312
JVM Heap: 56773920 Total Process: 113037312
JVM Heap: 56773920 Total Process: 113037312
JVM Heap: 52579552 Total Process: 113037312
JVM Heap: 52579552 Total Process: 113037312
JVM Heap: 52579552 Total Process: 113037312
JVM Heap: 52579552 Total Process: 113037312
JVM Heap: 48385184 Total Process: 113037312
JVM Heap: 48385184 Total Process: 113037312
JVM Heap: 48385184 Total Process: 113037312
JVM Heap: 48385184 Total Process: 113037312
JVM Heap: 44190816 Total Process: 113037312
JVM Heap: 44190816 Total Process: 113037312
JVM Heap: 44190816 Total Process: 113037312
JVM Heap: 44190816 Total Process: 113037312
JVM Heap: 39996448 Total Process: 113037312
JVM Heap: 39996448 Total Process: 113037312
JVM Heap: 39996448 Total Process: 113037312
JVM Heap: 39996448 Total Process: 113037312
JVM Heap: 35802080 Total Process: 113037312
JVM Heap: 35802080 Total Process: 113037312
JVM Heap: 35802080 Total Process: 113037312
JVM Heap: 35802080 Total Process: 113037312
JVM Heap: 31607712 Total Process: 113037312
JVM Heap: 31607712 Total Process: 113037312
JVM Heap: 31607712 Total Process: 113037312
JVM Heap: 31607712 Total Process: 113037312
JVM Heap: 27413344 Total Process: 113037312
JVM Heap: 27413344 Total Process: 111534080
JVM Heap: 27413344 Total Process: 106262528
JVM Heap: 27413344 Total Process: 98320384
JVM Heap: 23218976 Total Process: 83288064
JVM Heap: 23218976 Total Process: 83288064
JVM Heap: 23218976 Total Process: 83288064
JVM Heap: 23218976 Total Process: 83288064
JVM Heap: 19024608 Total Process: 68194304
JVM Heap: 19024608 Total Process: 68194304
JVM Heap: 19024608 Total Process: 68194304
JVM Heap: 19024608 Total Process: 68194304
JVM Heap: 14830240 Total Process: 53166080
JVM Heap: 14830240 Total Process: 53166080
JVM Heap: 14830240 Total Process: 53166080
JVM Heap: 11684464 Total Process: 41893888
JVM Heap: 10635872 Total Process: 38199296
JVM Heap: 10635872 Total Process: 38199296
JVM Heap: 8538688 Total Process: 30687232
JVM Heap: 8538688 Total Process: 30687232
JVM Heap: 6435528 Total Process: 23150592
JVM Heap: 6435528 Total Process: 23150592
JVM Heap: 4338344 Total Process: 15634432
JVM Heap: 3289752 Total Process: 11943936
JVM Heap: 2241160 Total Process: 8450048
JVM Heap: 1192568 Total Process: 5181440
JVM Heap: 143976 Total Process: 5181440

Gruß Tom
 
Zurück