Limit the Java heap size to 1024 MB when 32-Bit JVM was detected.

This commit is contained in:
LoRd_MuldeR 2023-03-26 22:27:29 +02:00
parent 2d5b01092b
commit 9d27eb5a98

View File

@ -73,8 +73,22 @@ static const DWORD SPLASH_SCREEN_TIMEOUT = 30000U;
#error Unknown target platform! #error Unknown target platform!
#endif #endif
// Boolean value /* ======================================================================== */
/* Miscellaneous */
/* ======================================================================== */
#define BOOLIFY(X) ((X) ? TRUE : FALSE) #define BOOLIFY(X) ((X) ? TRUE : FALSE)
#define PERCENT(X) (bound_value(1U, (X), 100U) / 100.0)
static DWORD bound_value(const DWORD min_value, const DWORD value, const DWORD max_value)
{
return max(min_value, min(max_value, value));
}
static ULONGLONG div_ceil(const ULONGLONG value, const ULONGLONG divisor)
{
return (!(value % divisor)) ? (value / divisor) : ((value / divisor) + 1ULL);
}
/* ======================================================================== */ /* ======================================================================== */
/* String routines */ /* String routines */
@ -327,7 +341,7 @@ static BOOL running_on_64bit(void)
static ULONGLONG get_physical_memory_size() static ULONGLONG get_physical_memory_size()
{ {
MEMORYSTATUSEX memory_status; MEMORYSTATUSEX memory_status;
ZeroMemory(&memory_status, sizeof(MEMORYSTATUSEX)); SecureZeroMemory(&memory_status, sizeof(MEMORYSTATUSEX));
memory_status.dwLength = sizeof(MEMORYSTATUSEX); memory_status.dwLength = sizeof(MEMORYSTATUSEX);
if (GlobalMemoryStatusEx(&memory_status)) if (GlobalMemoryStatusEx(&memory_status))
{ {
@ -1030,7 +1044,7 @@ static BOOL detect_java_runtime_scan_liberica(const wchar_t *const key_name, con
return TRUE; return TRUE;
} }
static const wchar_t *detect_java_runtime(const DWORD required_bitness, const ULONGLONG required_ver_min, const ULONGLONG required_ver_max) static const wchar_t *detect_java_runtime(const DWORD required_bitness, const ULONGLONG required_ver_min, const ULONGLONG required_ver_max, DWORD *const bitness_out, ULONGLONG *const version_out)
{ {
typedef struct { UINT mode; const wchar_t *path; } reg_key_t; typedef struct { UINT mode; const wchar_t *path; } reg_key_t;
static const reg_key_t REG_KEYS[] = static const reg_key_t REG_KEYS[] =
@ -1044,8 +1058,8 @@ static const wchar_t *detect_java_runtime(const DWORD required_bitness, const UL
}; };
const wchar_t *runtime_path = NULL; const wchar_t *runtime_path = NULL;
DWORD bitness = 0U; *bitness_out = 0U;
ULONGLONG version = 0U; *version_out = 0U;
for (UINT i = running_on_64bit() ? 0U : 1U; i < 2U; ++i) for (UINT i = running_on_64bit() ? 0U : 1U; i < 2U; ++i)
{ {
@ -1056,7 +1070,7 @@ static const wchar_t *detect_java_runtime(const DWORD required_bitness, const UL
{ {
{ required_bitness, required_ver_min, required_ver_max }, { required_bitness, required_ver_min, required_ver_max },
{ HKEY_LOCAL_MACHINE, REG_KEYS[j].path, reg_view_64bit }, { HKEY_LOCAL_MACHINE, REG_KEYS[j].path, reg_view_64bit },
{ bitness, version, NULL } { *bitness_out, *version_out, NULL }
}; };
switch(REG_KEYS[j].mode) switch(REG_KEYS[j].mode)
{ {
@ -1072,14 +1086,14 @@ static const wchar_t *detect_java_runtime(const DWORD required_bitness, const UL
} }
if(search_state.result.runtime_path) if(search_state.result.runtime_path)
{ {
bitness = search_state.result.bitness; *bitness_out = search_state.result.bitness;
version = search_state.result.version; *version_out = search_state.result.version;
SET_STRING(runtime_path, search_state.result.runtime_path); SET_STRING(runtime_path, search_state.result.runtime_path);
} }
} }
} }
if (((required_bitness == 0U) || (bitness == required_bitness)) && (version >= required_ver_min) && (version < required_ver_max) && runtime_path) if (((required_bitness == 0U) || (*bitness_out == required_bitness)) && (*version_out >= required_ver_min) && (*version_out < required_ver_max) && runtime_path)
{ {
return runtime_path; return runtime_path;
} }
@ -1135,7 +1149,7 @@ static const wchar_t *get_commandline_args(const wchar_t *cmd_line)
} }
else else
{ {
return L""; return L""; /*no args*/
} }
} }
@ -1214,13 +1228,13 @@ static const wchar_t *encode_commandline_str(const wchar_t *const command_line)
return encoded; return encoded;
} }
const wchar_t *create_heap_size_parameters(const DWORD jvm_heap_percent_min, const DWORD jvm_heap_percent_max, const wchar_t *const jvm_extra_args) const wchar_t *create_heap_size_parameters(const DWORD jvm_heap_percent_min, const DWORD jvm_heap_percent_max, const wchar_t *const jvm_extra_args, const DWORD heap_size_limit)
{ {
const ULONGLONG physical_memory_size = get_physical_memory_size(); const ULONGLONG physical_memory_size = get_physical_memory_size();
if (physical_memory_size > 0ULL) if (physical_memory_size > 33554432ULL)
{ {
const DWORD heap_size_mbytes_min = ((jvm_heap_percent_min > 0U) && (jvm_heap_percent_min <= 100U)) ? ((DWORD)((((ULONGLONG)((jvm_heap_percent_min / (double)100U) * physical_memory_size)) + (BYTES_PER_MEGABYTE - 1U)) / BYTES_PER_MEGABYTE)) : 0U; const DWORD heap_size_mbytes_min = jvm_heap_percent_min ? bound_value(16U, (DWORD)div_ceil((ULONGLONG)(PERCENT(jvm_heap_percent_min) * physical_memory_size), BYTES_PER_MEGABYTE), heap_size_limit) : 0U;
const DWORD heap_size_mbytes_max = ((jvm_heap_percent_max > 0U) && (jvm_heap_percent_max <= 100U)) ? ((DWORD)((((ULONGLONG)((jvm_heap_percent_max / (double)100U) * physical_memory_size)) + (BYTES_PER_MEGABYTE - 1U)) / BYTES_PER_MEGABYTE)) : 0U; const DWORD heap_size_mbytes_max = jvm_heap_percent_max ? bound_value(16U, (DWORD)div_ceil((ULONGLONG)(PERCENT(jvm_heap_percent_max) * physical_memory_size), BYTES_PER_MEGABYTE), heap_size_limit) : 0U;
if ((heap_size_mbytes_min > 0U) && (heap_size_mbytes_max >= heap_size_mbytes_min)) if ((heap_size_mbytes_min > 0U) && (heap_size_mbytes_max >= heap_size_mbytes_min))
{ {
return AVAILABLE(jvm_extra_args) return AVAILABLE(jvm_extra_args)
@ -1230,8 +1244,8 @@ const wchar_t *create_heap_size_parameters(const DWORD jvm_heap_percent_min, con
else if ((heap_size_mbytes_min > 0U) || (heap_size_mbytes_max > 0U)) else if ((heap_size_mbytes_min > 0U) || (heap_size_mbytes_max > 0U))
{ {
return AVAILABLE(jvm_extra_args) return AVAILABLE(jvm_extra_args)
? aswprintf(L"-Xm%c%um %s", (heap_size_mbytes_min > 0U) ? L's' : L'x', (heap_size_mbytes_min > 0U) ? heap_size_mbytes_min : heap_size_mbytes_max, jvm_extra_args) ? aswprintf(L"-Xm%c%um %s", (heap_size_mbytes_max > 0U) ? L'x' : L's', (heap_size_mbytes_max > 0U) ? heap_size_mbytes_max : heap_size_mbytes_min, jvm_extra_args)
: aswprintf(L"-Xm%c%um", (heap_size_mbytes_min > 0U) ? L's' : L'x', (heap_size_mbytes_min > 0U) ? heap_size_mbytes_min : heap_size_mbytes_max); : aswprintf(L"-Xm%c%um", (heap_size_mbytes_max > 0U) ? L'x' : L's', (heap_size_mbytes_max > 0U) ? heap_size_mbytes_max : heap_size_mbytes_min);
} }
} }
return NULL; return NULL;
@ -1585,11 +1599,6 @@ static void destroy_window(HWND *const hwnd)
} }
} }
static DWORD bound_value(const DWORD min_value, const DWORD value, const DWORD max_value)
{
return max(min_value, min(max_value, value));
}
/* ======================================================================== */ /* ======================================================================== */
/* MAIN */ /* MAIN */
/* ======================================================================== */ /* ======================================================================== */
@ -1603,8 +1612,8 @@ static int launch5j_main(const HINSTANCE hinstance, const wchar_t *const cmd_lin
const wchar_t *app_heading = NULL, *mutex_name = NULL, *executable_path = NULL, *executable_directory = NULL, *jarfile_path = NULL, const wchar_t *app_heading = NULL, *mutex_name = NULL, *executable_path = NULL, *executable_directory = NULL, *jarfile_path = NULL,
*java_runtime_path = NULL, *jre_relative_path = NULL, *jvm_extra_args = NULL, *cmd_extra_args = NULL, *command_line = NULL; *java_runtime_path = NULL, *jre_relative_path = NULL, *jvm_extra_args = NULL, *cmd_extra_args = NULL, *command_line = NULL;
HANDLE mutex_handle = NULL; HANDLE mutex_handle = NULL;
DWORD java_required_bitness = 0U, jvm_heap_percent_min = 0U, jvm_heap_percent_max = 0U; DWORD java_required_bitness = 0U, jvm_heap_percent_min = 0U, jvm_heap_percent_max = 0U, jvm_bitness = 0U;
ULONGLONG java_required_ver_min = 0ULL, java_required_ver_max = 0ULL; ULONGLONG java_required_ver_min = 0ULL, java_required_ver_max = 0ULL, jvm_version = 0ULL;
HGDIOBJ splash_image = NULL; HGDIOBJ splash_image = NULL;
BOOL have_screen_created = FALSE; BOOL have_screen_created = FALSE;
PROCESS_INFORMATION process_info; PROCESS_INFORMATION process_info;
@ -1710,7 +1719,7 @@ static int launch5j_main(const HINSTANCE hinstance, const wchar_t *const cmd_lin
java_required_ver_min = load_java_version(hinstance, ID_STR_JAVAMIN, (8ull << 48)); java_required_ver_min = load_java_version(hinstance, ID_STR_JAVAMIN, (8ull << 48));
java_required_ver_max = load_java_version(hinstance, ID_STR_JAVAMAX, MAXULONGLONG); java_required_ver_max = load_java_version(hinstance, ID_STR_JAVAMAX, MAXULONGLONG);
java_required_bitness = load_java_bitness(hinstance, ID_STR_BITNESS); java_required_bitness = load_java_bitness(hinstance, ID_STR_BITNESS);
if (!(java_runtime_path = detect_java_runtime(java_required_bitness, java_required_ver_min, java_required_ver_max))) if (!(java_runtime_path = detect_java_runtime(java_required_bitness, java_required_ver_min, java_required_ver_max, &jvm_bitness, &jvm_version)))
{ {
show_message(hwnd, MB_ICONERROR | MB_TOPMOST, APP_HEADING, L"Java Runtime Environment (JRE) could not be found!"); show_message(hwnd, MB_ICONERROR | MB_TOPMOST, APP_HEADING, L"Java Runtime Environment (JRE) could not be found!");
show_jre_download_notice(hinstance, hwnd, APP_HEADING, java_required_bitness, java_required_ver_min); show_jre_download_notice(hinstance, hwnd, APP_HEADING, java_required_bitness, java_required_ver_min);
@ -1723,7 +1732,7 @@ static int launch5j_main(const HINSTANCE hinstance, const wchar_t *const cmd_lin
show_message(hwnd, MB_ICONERROR | MB_TOPMOST, APP_HEADING, L"The path of the Java runtime could not be determined!"); show_message(hwnd, MB_ICONERROR | MB_TOPMOST, APP_HEADING, L"The path of the Java runtime could not be determined!");
goto cleanup; goto cleanup;
} }
if (!BOOLIFY(file_is_executable(java_runtime_path))) if (!BOOLIFY(jvm_bitness = file_is_executable(java_runtime_path)))
{ {
show_message_format(hwnd, MB_ICONERROR | MB_TOPMOST, APP_HEADING, L"The Java runtime could not be found or is invalid:\n\n%s\n\n\nRe-installing the application may fix the problem!", java_runtime_path); show_message_format(hwnd, MB_ICONERROR | MB_TOPMOST, APP_HEADING, L"The Java runtime could not be found or is invalid:\n\n%s\n\n\nRe-installing the application may fix the problem!", java_runtime_path);
goto cleanup; goto cleanup;
@ -1739,7 +1748,7 @@ static int launch5j_main(const HINSTANCE hinstance, const wchar_t *const cmd_lin
jvm_heap_percent_max = bound_value(0U, load_uint32(hinstance, ID_STR_HEAPMAX, 0U), 100U); jvm_heap_percent_max = bound_value(0U, load_uint32(hinstance, ID_STR_HEAPMAX, 0U), 100U);
if ((jvm_heap_percent_min > 0U) || (jvm_heap_percent_max > 0U)) if ((jvm_heap_percent_min > 0U) || (jvm_heap_percent_max > 0U))
{ {
const wchar_t *const jvm_heap_size_args = create_heap_size_parameters(jvm_heap_percent_min, jvm_heap_percent_max, jvm_extra_args); const wchar_t *const jvm_heap_size_args = create_heap_size_parameters(jvm_heap_percent_min, jvm_heap_percent_max, jvm_extra_args, (jvm_bitness && (jvm_bitness < 64U)) ? 1024U : MAXDWORD);
if (jvm_heap_size_args) if (jvm_heap_size_args)
{ {
free((void*)jvm_extra_args); free((void*)jvm_extra_args);