簡體   English   中英

如何在基准測試中解釋高 Java 內存消耗

[英]How to explain high Java memory consumption in benchmark

我正在編寫一個小應用程序,它允許用戶對程序進行基准測試。 目前我正在分析一些測試程序的結果,我對我所看到的感到非常驚訝。 我用於測量的 PC 有 16GB RAM。 以下是蒙特卡洛積分算法的源代碼和結果。

這是 C# 源代碼:

private const long Iterations = 100000000;
static void Main(string[] args)
{
    Random rand = new Random();

    int underCurve = 0;

    for (int i = 0; i < Iterations; i++)
    {
        double x = rand.NextDouble();
        double y = rand.NextDouble();

        if (x * x + y * y <= 1.0)
        {
            underCurve++;
        }
    }
    Console.WriteLine(((double)underCurve / Iterations) * 4.0);
}

這是 C# 結果:

9785344
9711616
9633792
9691136
9740288
9691136
9768960
9662464
9695232
9662464

Minimum memory consumed = 9633792
Maximum memory consumed = 9785344
Maximum memory consumed = 9704243

這是Java源代碼:

private static long Iterations = 100000000;
public static void main(String[] args) {
    Random rand = new Random();

    int underCurve = 0;

    for (int i = 0; i < Iterations; i++){
        double x = rand.nextDouble();
        double y = rand.nextDouble();

        if (x * x + y * y <= 1.0){
            underCurve++;
        }
    }
    System.out.println(((double)underCurve/Iterations)* 4.0);
}

這是 Java 結果:

454193152
454152192
454201344
454238208
454098944
454258688
454144000
454135808
454189056
454115328

Minimum memory consumed = 454098944
Maximum memory consumed = 454258688
Average memory consumed = 454172672

這是我用來測量進程內存消耗的代碼:

private static long MeasureMemoryConsumption(String name, string workingDirectory, String arguments)
{
    Process process = new Process();
    process.StartInfo.WorkingDirectory = workingDirectory;
    process.StartInfo.FileName = name;
    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.Arguments = arguments;

    long peakMem = 0;
    Thread memMeasuringThread = new Thread(() =>
    {
        while (true)
        {
            try
            {
                process.Refresh();
                peakMem = peakMem < process.PrivateMemorySize64 ? process.PrivateMemorySize64 : peakMem;
            }
            catch (InvalidOperationException)
            {
                //ignore, process didn't start yet
            }
        }
    });

    memMeasuringThread.Start();
    process.Start();
    process.WaitForExit();
    memMeasuringThread.Abort();

    return peakMem;
}

在執行期間查看資源監視器時,我可以看到,雖然資源監視器中的“Private”值始終很小(大約 10 MB),但 Java 程序的“Commit”值卻很大(約 400 MB) . C# 版本不是這種情況。 我想這與問題有關,但是,在我的測量代碼中,我使用的是 PrivateMemorySize64 屬性。

我的問題是,Java 版本怎么可能比 C# 版本消耗更多的內存,如果是由於我的錯誤,我怎樣才能獲得更准確的測量結果?

小程序的內存占用始終是 Java 應用程序的一個問題。 如果你嘗試過一些像 leetcode 這樣的 OJ 服務,你會發現與 C/C++/Python/JS/C# 相比,Java 實現總是有更大的內存占用和更長的啟動時間:

在此處輸入圖片說明

不同的 JVM 有不同的啟動參數(例如JRockit: Tuning For a Small Memory Footprint ),也許您可​​以嘗試一下。

另外我認為這個答案可能會解釋一些事情

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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