Я пишу небольшое приложение, которое позволяет пользователям тестировать программы. В настоящее время я анализирую результаты некоторых тестовых программ, и я очень удивлен тем, что вижу. ПК, который я использую для измерений, имеет ОЗУ 16 ГБ. Ниже приведены исходный код и результаты для алгоритма интеграции Монте-Карло.Как объяснить высокую загрузку памяти Java в эталонном
Это источник 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 МБ), значение «Commit» огромно (~ 400 МБ) для Java-программ. Это не относится к версии C#. Я полагаю, что это имеет какое-то отношение к проблеме, однако в моем измерительном коде я использую свойство PrivateMemorySize64.
Мой вопрос: насколько возможно, что версия Java потребляет гораздо больше памяти, чем версия C#, и если это связано с ошибкой с моей стороны, как я могу получить более точные измерения?
Я мало что знаю об этом, но не потому, что Java задерживает управление памятью (сборку мусора), чтобы ускорить процесс. –
Если вы не даете Java никаких параметров '-Xms/-Xmx', они с радостью выделяют 1/4 вашей общей памяти в JVM и используют ее с безрассудным отказом. – Kayaman