[英]Java : Why there is no difference in JVM Heap Size even after Object Creation
我試圖找出JVM堆大小與對象創建的不同之處。
例如,如果您看到下面的程序,我將在for循環中創建10000個字符串對象,但在JVM環境中,堆大小仍然沒有區別。
public class One {
public static void main(String args[]) {
long heapSizebefore = Runtime.getRuntime().totalMemory();
System.out.println("heapSizebefore" + heapSizebefore);
for (int i = 0; i <= 10000; i++) {
String str = new String();
}
long heapSizeafter = Runtime.getRuntime().totalMemory();
System.out.println("heapSizeafter" + heapSizeafter);
}
}
對totalMemory
的調用僅提供Java進程保留的內存量。 這並不意味着它正在被堆中的對象積極填充。 正如javadocs所說,它是當前和將來對象可用的內存總量。
實際上,Java寧願從底層操作系統請求大塊內存,而不是每次創建新對象時都必須調用malloc
(或等效方法)。
如果要跟蹤堆的實際大小,則可以使用JConsole / JVisualVM之類的工具簡單地實時執行此操作,或者使用內存分析器進行更詳細的操作。 如果要以編程方式進行操作,則需要為復雜的東西注冊一個代理,但是堆詳細信息通過JMX公開。 看一下java.lang:Memory
MBean的HeapMemoryUsage
屬性(JConsole用於顯示內存圖表的屬性)。
由於JIT沒有副作用,因此它還可能優化整個for
循環。
兩個原因:
基本上我想知道為什么我們在Java中使用靜態方法。
因為靜態方法比實例方法簡單。
所以我的問題是節省內存(通過對象創建),我們使用靜態方法
不。您應該有針對性地進行編碼,並且僅創建實際需要的東西。 您可以在需要時創建實例,而在不需要時則不創建實例。 這不是出於性能原因,而是為了減少代碼的概念量。 如果您必須維護您的代碼或其他代碼,則需要找出為什么要做某件事,並且要花很多時間才能確定毫無意義的代碼確實毫無意義。 即,尋找不存在的東西比尋找不存在的東西需要更長的時間。
為了支持多線程內存分配,每個線程都有一個線程本地分配緩沖區或TLAB 。
可用空間僅顯示公共池中有多少可用空間,而不能顯示每個線程的TLAB中可用的空間。 如果分配足夠的字符串,則在加載另一個塊時,您會發現內存使用量突然增加。
您可以使用-XX:-UseTLAB
將其關閉
// -XX:+UseTLAB heapUsedBefore: 5,368,848 heapUsedAfter: 5,368,848
// -XX:-UseTLAB heapUsedBefore: 535,048 heapUsedAfter: 535,096
public class One {
public static void main(String... args) {
Runtime runtime = Runtime.getRuntime();
long heapUsedBefore = runtime.totalMemory() - runtime.freeMemory();
String str = new String();
long heapUsedAfter = runtime.totalMemory() - runtime.freeMemory();
System.out.printf("heapUsedBefore: %,d heapUsedAfter: %,d%n",
heapUsedBefore, heapUsedAfter);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.