簡體   English   中英

Java:為什么即使在創建對象之后,JVM堆大小也沒有差異

[英]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循環。

兩個原因:

  1. 您正在測量為堆保留的內存量,而不是活動對象大小的總和。
  2. 無論如何,您都不保留對分配的字符串的引用,因此JVM可以隨時隨意對其進行垃圾回收。

基本上我想知道為什么我們在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM