logic: fixed application crash on windows if JVM tries to allocate too much memory by reducing the amount of allocated memory to the available size.
This commit is contained in:
@@ -616,6 +616,8 @@ add_files(
|
||||
utility/utilityMath.h
|
||||
utility/utilityUuid.cpp
|
||||
utility/utilityUuid.h
|
||||
utility/utilityWindows.cpp
|
||||
utility/utilityWindows.h
|
||||
utility/utilityXml.cpp
|
||||
utility/utilityXml.h
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "utility/utilityWindows.h"
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
unsigned long utility::getLargestByteSizeOfAllocatableMemory()
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
unsigned long start = 0;
|
||||
bool recording = false;
|
||||
unsigned long freestart = 0, largestFreestart = 0;
|
||||
__int64 free = 0, largestFree = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
SIZE_T s = VirtualQuery((LPCVOID)start, &mbi, sizeof(mbi));
|
||||
if (s != sizeof(mbi)) break;
|
||||
|
||||
if (mbi.State == MEM_FREE)
|
||||
{
|
||||
if (!recording) freestart = start;
|
||||
|
||||
free += mbi.RegionSize;
|
||||
recording = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (recording)
|
||||
{
|
||||
if (free > largestFree)
|
||||
{
|
||||
largestFree = free;
|
||||
largestFreestart = freestart;
|
||||
}
|
||||
}
|
||||
free = 0;
|
||||
recording = false;
|
||||
}
|
||||
start += mbi.RegionSize;
|
||||
}
|
||||
|
||||
return largestFree;
|
||||
}
|
||||
|
||||
#endif // WIN32
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef UTILITY_WINDOWS_H
|
||||
#define UTILITY_WINDOWS_H
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
namespace utility
|
||||
{
|
||||
unsigned long getLargestByteSizeOfAllocatableMemory();
|
||||
}
|
||||
|
||||
#endif // WIN32
|
||||
|
||||
#endif // UTILITY_WINDOWS_H
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "settings/ApplicationSettings.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/utilityLibrary.h"
|
||||
#include "utility/utilityWindows.h"
|
||||
|
||||
void JavaEnvironmentFactory::createInstance(std::string classPath, std::string& errorString)
|
||||
{
|
||||
@@ -41,7 +42,22 @@ void JavaEnvironmentFactory::createInstance(std::string classPath, std::string&
|
||||
|
||||
s_classPath = classPath;
|
||||
|
||||
const int jvmMaximumMemory = ApplicationSettings::getInstance()->getJavaMaximumMemory();
|
||||
int jvmMaximumMemory = ApplicationSettings::getInstance()->getJavaMaximumMemory();
|
||||
|
||||
#ifdef WIN32
|
||||
if (jvmMaximumMemory > 0)
|
||||
{
|
||||
const float underestimationFactor = 0.8f;
|
||||
const int maximumMB = utility::getLargestByteSizeOfAllocatableMemory() / 1024 / 1024 * underestimationFactor;
|
||||
if (jvmMaximumMemory > maximumMB)
|
||||
{
|
||||
LOG_WARNING("Selected amount of maximum JVM memory of " + std::to_string(jvmMaximumMemory) + " MB exceeds maximum allocatable "
|
||||
"memory on system. Correcting selected value to " + std::to_string(maximumMB) + " MB.");
|
||||
jvmMaximumMemory = maximumMB;
|
||||
}
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
const int optionCount = (jvmMaximumMemory < 0 ? 2 : 3);
|
||||
const std::string maximumMemoryOprionString = "-Xmx" + std::to_string(jvmMaximumMemory) + "m";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user