Dieses Beispiel von William Brendel kann von Nutzen sein.
BEARBEITEN: Ich habe dieses Beispiel ursprünglich bereitgestellt (Link zu William Brendels Antwort zu einem anderen Thema). Der Ersteller dieses Themas (Steve M) wollte eine plattformübergreifende Java-Anwendung erstellen. Insbesondere versuchte der Benutzer, ein Mittel zu finden, mit dem die Ressourcen des laufenden Computers (Speicherplatz, CPU- und Speichernutzung) bewertet werden können.
Dies ist eine Inline-Abschrift der Antwort in diesem Thema. Zu diesem Thema wurde jedoch darauf hingewiesen, dass dies nicht die ideale Lösung ist, obwohl meine Antwort als akzeptiert markiert ist.
public class Main {
public static void main(String[] args) {
System.out.println("Available processors (cores): " +
Runtime.getRuntime().availableProcessors());
System.out.println("Free memory (bytes): " +
Runtime.getRuntime().freeMemory());
long maxMemory = Runtime.getRuntime().maxMemory();
System.out.println("Maximum memory (bytes): " +
(maxMemory == Long.MAX_VALUE ? "no limit" : maxMemory));
System.out.println("Total memory (bytes): " +
Runtime.getRuntime().totalMemory());
File[] roots = File.listRoots();
for (File root : roots) {
System.out.println("File system root: " + root.getAbsolutePath());
System.out.println("Total space (bytes): " + root.getTotalSpace());
System.out.println("Free space (bytes): " + root.getFreeSpace());
System.out.println("Usable space (bytes): " + root.getUsableSpace());
}
}
}
Benutzer Christian Fries weist darauf hin, dass es falsch ist anzunehmen, dass Runtime.getRuntime().freeMemory()
Sie die Menge an Speicher erhalten, die zugewiesen werden kann, bis ein Fehler aufgrund von Speichermangel auftritt.
Aus der Dokumentation geht hervor , dass die Unterschrift Runtime.getRuntime().freeMemory()
als solche zurückgegeben wird:
Rückgabe: Eine Annäherung an die derzeit für zukünftige zugewiesene Objekte verfügbare Gesamtmenge an Speicher, gemessen in Byte.
Benutzer Christian Fries behauptet jedoch, dass diese Funktion möglicherweise falsch interpretiert wird. Er behauptet, dass die ungefähre Speichermenge, die zugewiesen werden kann, bis ein Fehler aufgrund von Speichermangel auftritt (der freie Speicher), wahrscheinlich gegeben ist durch:
long presumableFreeMemory = Runtime.getRuntime().maxMemory() - allocatedMemory;
Mit allocatedMemory
gegeben von:
long allocatedMemory =
(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory());
Der Schlüssel hier ist eine Diskrepanz zwischen dem Konzept des freien Speichers. Eine Sache ist der Speicher, den das Betriebssystem der Java Virtual Machine zur Verfügung stellt. Eine andere ist die Gesamtmenge an Bytes, die die Blöcke von Speicherblöcken umfasst, die tatsächlich von der Java Virtual Machine selbst verwendet werden.
In Anbetracht der Tatsache, dass der für Java-Anwendungen bereitgestellte Speicher von der Java Virtual Machine in Blöcken verwaltet wird, stimmt die für die Java Virtual Machine verfügbare Menge an freiem Speicher möglicherweise nicht genau mit dem für eine Java-Anwendung verfügbaren Speicher überein.
Insbesondere bezeichnet Christian Fries die Verwendung der Flags -mx
oder -Xmx
, um die maximale Speichermenge festzulegen, die für die Java Virtual Machine verfügbar ist. Er stellt folgende Funktionsunterschiede fest:
Runtime.getRuntime().maxMemory();
Runtime.getRuntime().totalMemory();
Runtime.getRuntime().freeMemory();
Christian schließt seine Antwort mit der Feststellung, dass Runtime.getRuntime().freeMemory()
tatsächlich das zurückgegeben wird, was man als vermutliches freies Gedächtnis bezeichnen kann; Selbst wenn eine zukünftige Speicherzuweisung den von dieser Funktion zurückgegebenen Wert nicht überschreitet, java.lang.OutOfMemoryError
kann möglicherweise noch ein vom Hostsystem zugewiesener Speicherblock erzeugt werden, wenn die Java Virtual Machine noch nicht den tatsächlichen vom Hostsystem zugewiesenen Speicherblock empfangen hat .
Letztendlich hängt die richtige Methode in unterschiedlichem Maße von den Besonderheiten Ihrer Anwendung ab.
Ich biete einen weiteren Link an, der nützlich sein kann. Diese Frage wurde vom Benutzer Richard Dormand gestellt und von stone333 zur Bestimmung der verwendeten Standard-Java-Heap-Größe beantwortet .
Hinweis: Alle bisherigen Antworten, auch die akzeptierte, scheinen die Frage zu beantworten, indem sie sagen, dass
Runtime.getRuntime().freeMemory()
Sie die Menge an Speicher erhalten, die zugewiesen werden kann, bis ein Fehler aufgrund von Speichermangel auftritt. Allerdings: das ist falsch.Die ungefähre Speichermenge, die zugewiesen werden kann, bis ein Fehler aufgrund von Speichermangel auftritt, dh der freie Speicher ist wahrscheinlich
long presumableFreeMemory = Runtime.getRuntime().maxMemory() - allocatedMemory;
wo
long allocatedMemory = (Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory());
Erläuterung: Wenn Sie die JVM über einen Parameter -mx (oder -Xmx) starten, geben Sie die maximale Menge an, die der JVM zur Verfügung steht.
Runtime.getRuntime().maxMemory()
wird Ihnen diesen Betrag geben. Aus dieser Menge an Systemspeicher weist die JVM Speicher in Blöcken zu, beispielsweise Blöcke von 64 MB. Zu Beginn weist die JVM nur einen solchen Block aus dem System zu und nicht den vollen Betrag.Runtime.getRuntime().totalMemory()
gibt den vom System zugewiesenen Gesamtspeicher an, währendRuntime.getRuntime().freeMemory()
Sie den freien Speicher innerhalb des zugewiesenen Gesamtspeichers erhalten.Daher:
long definitelyFreeMemory = Runtime.getRuntime().freeMemory();
ist der freie Speicher, der bereits von der JVM reserviert wurde, aber wahrscheinlich nur eine kleine Menge. Und Sie werden wahrscheinlich bekommen
presumableFreeMemory
. Natürlich kann es zu einer Ausnahme wegen Speichermangels kommen, selbst wenn Sie versucht haben, einen Betrag zuzuweisen, der kleiner als istpresumableFreeMemory
. Dies kann passieren, wenn die JVM nicht den nächsten Speicherblock vom System erhält. Auf den meisten Systemen wird dies jedoch niemals passieren und das System wird eher mit dem Austausch beginnen - eine Situation, die Sie gerne vermeiden. Zur ursprünglichen Frage: Wenn -mx auf einen vernünftigen Wert eingestellt ist,presumableFreeMemory
ist dies ein guter Indikator für den freien Speicher.quelle
maxMemory()
state: "Wenn es keine inhärente Grenze gibt, wird der Wert Long.MAX_VALUE zurückgegeben." Es lohnt sich wahrscheinlich, dies zu überprüfen, da die "kostenlose" Nummer, die es Ihnen geben wird, Unsinn sein wird.Zusätzlich zur Verwendung der Runtime-Methoden können Sie mithilfe von zusätzliche Speicherinformationen abrufen
Jede MemoryUsage bietet Init- , Used- , Commit- und Max-Werte. Dies kann hilfreich sein, wenn Sie einen Speichermonitor-Thread erstellen, der den Speicher abfragt und protokolliert und Ihnen einen Verlauf der Speichernutzung im Laufe der Zeit liefert. Manchmal ist es hilfreich, die Speichernutzung im Laufe der Zeit zu sehen, die zu den Fehlern führt.
Wenn Sie dies wirklich auf die Spitze treiben möchten, erstellen Sie einen Heap-Dump-Thread. Überwachen Sie Ihre Speichernutzung im Laufe der Zeit und gehen Sie wie folgt vor, wenn bestimmte Schwellenwerte überschritten werden (dies funktioniert unter JBoss 5.0 - Ihr Kilometerstand kann variieren):
// init code MBeanServer server = ManagementFactory.getPlatformMBeanServer(); HotSpotDiagnosticMXBean diagBean = ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class); // loop code // add some code to figure if we have passed some threshold, then File heapFile = new File(outputDir, "heap-" + curThreshold + ".hprof"); log.info("Dumping heap file " + heapFile.getAbsolutePath()); diagBean.dumpHeap(heapFile.getAbsolutePath(), true);
Später können Sie diese Heap-Dump-Dateien mit dem Eclipse Memory Analyzer oder ähnlichen Tools überprüfen, um nach Speicherlecks usw. zu suchen.
quelle
Neben der anderen Antwort möchte ich darauf hinweisen, dass dies nicht unbedingt eine gute Idee ist, da Ihre App möglicherweise einen Cache enthält, der SoftReferences verwendet .
Ein solcher Cache würde Speicher freigeben, sobald die JVM ihre Speichergrenzen erreicht. Das Zuweisen von Speicher, selbst wenn nicht genügend freier Speicher vorhanden ist, würde zuerst dazu führen, dass Speicher durch die weichen Referenzen freigegeben wird, und ihn für die Zuweisung verfügbar machen.
quelle
OSHI
Fügen Sie mithilfe der folgenden Maven-Abhängigkeit hinzu, um den für das Betriebssystem verfügbaren Speicher zu erhalten :Verwenden Sie dann in Java den folgenden Code:
SystemInfo si = new SystemInfo(); HardwareAbstractionLayer hal = si.getHardware(); long availableMemory = hal.getMemory().getAvailable();
quelle
Sie können jederzeit anrufen
Runtime.getRuntime().freeMemory()
.Die andere Hälfte des Problems, die Kosten für Objekte zu ermitteln, erscheint mir problematischer.
Ich denke, eine bessere Lösung wäre es, herauszufinden, wie Sie Ihre Webdienste gruppieren und skalieren können, damit sie 150% der Nennlast ordnungsgemäß akzeptieren können, ohne neue Verbindungen zu verweigern. Klingt so, als würde eine Größenübung eine bessere Lösung bringen als ein Code-Hack.
quelle
long freeMemory = Runtime.getRuntime().freeMemory();
quelle
Runtime.getRuntime().freeMemory()
ist eine Möglichkeit, in diesem Moment zur Laufzeit freien Speicher für JVM zu erhalten. Ist es ein guter Weg (oder nicht), hängt es vollständig von Ihrer Anwendung ab.quelle
Um die Gesamtzahl , den verwendeten und den freien Speicher der physischen Maschine abzurufen , können Sie diese auch mithilfe von Java
Runtime.exec()
mit dem Befehlsargument abrufenfree -m
und dann wie folgt interpretieren:Runtime runtime = Runtime.getRuntime(); BufferedReader br = new BufferedReader( new InputStreamReader(runtime.exec("free -m").getInputStream())); String line; String memLine = ""; int index = 0; while ((line = br.readLine()) != null) { if (index == 1) { memLine = line; } index++; } // total used free shared buff/cache available // Mem: 15933 3153 9683 310 3097 12148 // Swap: 3814 0 3814 List<String> memInfoList = Arrays.asList(memLine.split("\\s+")); int totalSystemMemory = Integer.parseInt(memInfoList.get(1)); int totalSystemUsedMemory = Integer.parseInt(memInfoList.get(2)); int totalSystemFreeMemory = Integer.parseInt(memInfoList.get(3)); System.out.println("Total system memory in mb: " + totalSystemMemory); System.out.println("Total system used memory in mb: " + totalSystemUsedMemory); System.out.println("Total system free memory in mb: " + totalSystemFreeMemory);
quelle