简体   繁体   English

如何在基准测试中解释高 Java 内存消耗

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

I'm writing a small application which allows users to benchmark programs.我正在编写一个小应用程序,它允许用户对程序进行基准测试。 Currently I'm analysing the results of some test programs and I am quite surprised by what I am seeing.目前我正在分析一些测试程序的结果,我对我所看到的感到非常惊讶。 The PC I am using for the measurements has 16GB RAM.我用于测量的 PC 有 16GB RAM。 Following are the source code and results for the Monte Carlo Integration algorithm.以下是蒙特卡洛积分算法的源代码和结果。

This is the C# source code:这是 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);
}

And here are the C# results:这是 C# 结果:

9785344
9711616
9633792
9691136
9740288
9691136
9768960
9662464
9695232
9662464

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

This is the Java source code:这是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);
}

And here are the Java results:这是 Java 结果:

454193152
454152192
454201344
454238208
454098944
454258688
454144000
454135808
454189056
454115328

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

This is the code I use to measure the memory consumption of the processes:这是我用来测量进程内存消耗的代码:

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;
}

When taking a look at the resource monitor during execution, I can see that while the "Private" value in the resource monitor always stays quite small (around 10 MB), the "Commit" value is huge (~400 MB) for Java programs.在执行期间查看资源监视器时,我可以看到,虽然资源监视器中的“Private”值始终很小(大约 10 MB),但 Java 程序的“Commit”值却很大(约 400 MB) . This is not the case for the C# version. C# 版本不是这种情况。 I suppose this has something to do with the problem, however, in my measuring code I am using the PrivateMemorySize64 property.我想这与问题有关,但是,在我的测量代码中,我使用的是 PrivateMemorySize64 属性。

My question is, how is it possible that the Java version consumes so much more memory than the C# version, and if it is due to an error on my part, how can I get more accurate measurements?我的问题是,Java 版本怎么可能比 C# 版本消耗更多的内存,如果是由于我的错误,我怎样才能获得更准确的测量结果?

Memory footprint for small program is always an issue for java applications.小程序的内存占用始终是 Java 应用程序的一个问题。 If you tried some OJ service like leetcode, you'll see that Java implementations are always has larger memory footprint and longer startup time comparing to C/C++/Python/JS/C#:如果你尝试过一些像 leetcode 这样的 OJ 服务,你会发现与 C/C++/Python/JS/C# 相比,Java 实现总是有更大的内存占用和更长的启动时间:

在此处输入图片说明

Different JVM has different startup arguments (eg JRockit: Tuning For a Small Memory Footprint ) and maybe you could have a try.不同的 JVM 有不同的启动参数(例如JRockit: Tuning For a Small Memory Footprint ),也许您可​​以尝试一下。

Also I think this answer might explain something .另外我认为这个答案可能会解释一些事情

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM