提交 babbf056 编写于 作者: T tschatzl

8006088: Incompatible heap size flags accepted by VM

Summary: Make processing of minimum, initial and maximum heap size more intiutive by removing previous limitations on allowed values, and make error reporting consistent. Further, fix errors in ergonomic heap sizing.
Reviewed-by: johnc, jwilhelm, tamao
上级 bbb0dffc
...@@ -55,6 +55,10 @@ void CollectorPolicy::initialize_flags() { ...@@ -55,6 +55,10 @@ void CollectorPolicy::initialize_flags() {
err_msg("max_alignment: " SIZE_FORMAT " not aligned by min_alignment: " SIZE_FORMAT, err_msg("max_alignment: " SIZE_FORMAT " not aligned by min_alignment: " SIZE_FORMAT,
max_alignment(), min_alignment())); max_alignment(), min_alignment()));
if (MaxHeapSize < InitialHeapSize) {
vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
}
if (MetaspaceSize > MaxMetaspaceSize) { if (MetaspaceSize > MaxMetaspaceSize) {
MaxMetaspaceSize = MetaspaceSize; MaxMetaspaceSize = MetaspaceSize;
} }
...@@ -78,21 +82,9 @@ void CollectorPolicy::initialize_flags() { ...@@ -78,21 +82,9 @@ void CollectorPolicy::initialize_flags() {
} }
void CollectorPolicy::initialize_size_info() { void CollectorPolicy::initialize_size_info() {
// User inputs from -mx and ms are aligned // User inputs from -mx and ms must be aligned
set_initial_heap_byte_size(InitialHeapSize); set_min_heap_byte_size(align_size_up(Arguments::min_heap_size(), min_alignment()));
if (initial_heap_byte_size() == 0) { set_initial_heap_byte_size(align_size_up(InitialHeapSize, min_alignment()));
set_initial_heap_byte_size(NewSize + OldSize);
}
set_initial_heap_byte_size(align_size_up(_initial_heap_byte_size,
min_alignment()));
set_min_heap_byte_size(Arguments::min_heap_size());
if (min_heap_byte_size() == 0) {
set_min_heap_byte_size(NewSize + OldSize);
}
set_min_heap_byte_size(align_size_up(_min_heap_byte_size,
min_alignment()));
set_max_heap_byte_size(align_size_up(MaxHeapSize, max_alignment())); set_max_heap_byte_size(align_size_up(MaxHeapSize, max_alignment()));
// Check heap parameter properties // Check heap parameter properties
...@@ -237,9 +229,6 @@ void TwoGenerationCollectorPolicy::initialize_flags() { ...@@ -237,9 +229,6 @@ void TwoGenerationCollectorPolicy::initialize_flags() {
GenCollectorPolicy::initialize_flags(); GenCollectorPolicy::initialize_flags();
OldSize = align_size_down(OldSize, min_alignment()); OldSize = align_size_down(OldSize, min_alignment());
if (NewSize + OldSize > MaxHeapSize) {
MaxHeapSize = NewSize + OldSize;
}
if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(NewSize)) { if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(NewSize)) {
// NewRatio will be used later to set the young generation size so we use // NewRatio will be used later to set the young generation size so we use
...@@ -254,6 +243,27 @@ void TwoGenerationCollectorPolicy::initialize_flags() { ...@@ -254,6 +243,27 @@ void TwoGenerationCollectorPolicy::initialize_flags() {
} }
MaxHeapSize = align_size_up(MaxHeapSize, max_alignment()); MaxHeapSize = align_size_up(MaxHeapSize, max_alignment());
// adjust max heap size if necessary
if (NewSize + OldSize > MaxHeapSize) {
if (FLAG_IS_CMDLINE(MaxHeapSize)) {
// somebody set a maximum heap size with the intention that we should not
// exceed it. Adjust New/OldSize as necessary.
uintx calculated_size = NewSize + OldSize;
double shrink_factor = (double) MaxHeapSize / calculated_size;
// align
NewSize = align_size_down((uintx) (NewSize * shrink_factor), min_alignment());
// OldSize is already aligned because above we aligned MaxHeapSize to
// max_alignment(), and we just made sure that NewSize is aligned to
// min_alignment(). In initialize_flags() we verified that max_alignment()
// is a multiple of min_alignment().
OldSize = MaxHeapSize - NewSize;
} else {
MaxHeapSize = NewSize + OldSize;
}
}
// need to do this again
MaxHeapSize = align_size_up(MaxHeapSize, max_alignment());
always_do_update_barrier = UseConcMarkSweepGC; always_do_update_barrier = UseConcMarkSweepGC;
// Check validity of heap flags // Check validity of heap flags
......
...@@ -93,6 +93,15 @@ WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name)) ...@@ -93,6 +93,15 @@ WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name))
return closure.found(); return closure.found();
WB_END WB_END
WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) {
CollectorPolicy * p = Universe::heap()->collector_policy();
gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap "
SIZE_FORMAT" Maximum heap "SIZE_FORMAT" Min alignment "SIZE_FORMAT" Max alignment "SIZE_FORMAT,
p->min_heap_byte_size(), p->initial_heap_byte_size(), p->max_heap_byte_size(),
p->min_alignment(), p->max_alignment());
}
WB_END
#if INCLUDE_ALL_GCS #if INCLUDE_ALL_GCS
WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj)) WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj))
G1CollectedHeap* g1 = G1CollectedHeap::heap(); G1CollectedHeap* g1 = G1CollectedHeap::heap();
...@@ -386,6 +395,7 @@ static JNINativeMethod methods[] = { ...@@ -386,6 +395,7 @@ static JNINativeMethod methods[] = {
CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;", CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
(void*) &WB_ParseCommandLine (void*) &WB_ParseCommandLine
}, },
{CC"printHeapSizes", CC"()V", (void*)&WB_PrintHeapSizes },
#if INCLUDE_ALL_GCS #if INCLUDE_ALL_GCS
{CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark}, {CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark},
{CC"g1IsHumongous", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous }, {CC"g1IsHumongous", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous },
......
...@@ -1617,30 +1617,38 @@ void Arguments::set_heap_size() { ...@@ -1617,30 +1617,38 @@ void Arguments::set_heap_size() {
FLAG_SET_ERGO(uintx, MaxHeapSize, (uintx)reasonable_max); FLAG_SET_ERGO(uintx, MaxHeapSize, (uintx)reasonable_max);
} }
// If the initial_heap_size has not been set with InitialHeapSize // If the minimum or initial heap_size have not been set or requested to be set
// or -Xms, then set it as fraction of the size of physical memory, // ergonomically, set them accordingly.
// respecting the maximum and minimum sizes of the heap. if (InitialHeapSize == 0 || min_heap_size() == 0) {
if (FLAG_IS_DEFAULT(InitialHeapSize)) {
julong reasonable_minimum = (julong)(OldSize + NewSize); julong reasonable_minimum = (julong)(OldSize + NewSize);
reasonable_minimum = MIN2(reasonable_minimum, (julong)MaxHeapSize); reasonable_minimum = MIN2(reasonable_minimum, (julong)MaxHeapSize);
reasonable_minimum = limit_by_allocatable_memory(reasonable_minimum); reasonable_minimum = limit_by_allocatable_memory(reasonable_minimum);
julong reasonable_initial = phys_mem / InitialRAMFraction; if (InitialHeapSize == 0) {
julong reasonable_initial = phys_mem / InitialRAMFraction;
reasonable_initial = MAX2(reasonable_initial, reasonable_minimum); reasonable_initial = MAX3(reasonable_initial, reasonable_minimum, (julong)min_heap_size());
reasonable_initial = MIN2(reasonable_initial, (julong)MaxHeapSize); reasonable_initial = MIN2(reasonable_initial, (julong)MaxHeapSize);
reasonable_initial = limit_by_allocatable_memory(reasonable_initial); reasonable_initial = limit_by_allocatable_memory(reasonable_initial);
if (PrintGCDetails && Verbose) { if (PrintGCDetails && Verbose) {
// Cannot use gclog_or_tty yet. // Cannot use gclog_or_tty yet.
tty->print_cr(" Initial heap size " SIZE_FORMAT, (uintx)reasonable_initial); tty->print_cr(" Initial heap size " SIZE_FORMAT, (uintx)reasonable_initial);
tty->print_cr(" Minimum heap size " SIZE_FORMAT, (uintx)reasonable_minimum); }
FLAG_SET_ERGO(uintx, InitialHeapSize, (uintx)reasonable_initial);
}
// If the minimum heap size has not been set (via -Xms),
// synchronize with InitialHeapSize to avoid errors with the default value.
if (min_heap_size() == 0) {
set_min_heap_size(MIN2((uintx)reasonable_minimum, InitialHeapSize));
if (PrintGCDetails && Verbose) {
// Cannot use gclog_or_tty yet.
tty->print_cr(" Minimum heap size " SIZE_FORMAT, min_heap_size());
}
} }
FLAG_SET_ERGO(uintx, InitialHeapSize, (uintx)reasonable_initial);
set_min_heap_size((uintx)reasonable_minimum);
} }
} }
...@@ -2426,7 +2434,8 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, ...@@ -2426,7 +2434,8 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
// -Xms // -Xms
} else if (match_option(option, "-Xms", &tail)) { } else if (match_option(option, "-Xms", &tail)) {
julong long_initial_heap_size = 0; julong long_initial_heap_size = 0;
ArgsRange errcode = parse_memory_size(tail, &long_initial_heap_size, 1); // an initial heap size of 0 means automatically determine
ArgsRange errcode = parse_memory_size(tail, &long_initial_heap_size, 0);
if (errcode != arg_in_range) { if (errcode != arg_in_range) {
jio_fprintf(defaultStream::error_stream(), jio_fprintf(defaultStream::error_stream(),
"Invalid initial heap size: %s\n", option->optionString); "Invalid initial heap size: %s\n", option->optionString);
...@@ -2437,7 +2446,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, ...@@ -2437,7 +2446,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
// Currently the minimum size and the initial heap sizes are the same. // Currently the minimum size and the initial heap sizes are the same.
set_min_heap_size(InitialHeapSize); set_min_heap_size(InitialHeapSize);
// -Xmx // -Xmx
} else if (match_option(option, "-Xmx", &tail)) { } else if (match_option(option, "-Xmx", &tail) || match_option(option, "-XX:MaxHeapSize=", &tail)) {
julong long_max_heap_size = 0; julong long_max_heap_size = 0;
ArgsRange errcode = parse_memory_size(tail, &long_max_heap_size, 1); ArgsRange errcode = parse_memory_size(tail, &long_max_heap_size, 1);
if (errcode != arg_in_range) { if (errcode != arg_in_range) {
......
...@@ -2968,7 +2968,7 @@ class CommandLineFlags { ...@@ -2968,7 +2968,7 @@ class CommandLineFlags {
\ \
/* gc parameters */ \ /* gc parameters */ \
product(uintx, InitialHeapSize, 0, \ product(uintx, InitialHeapSize, 0, \
"Initial heap size (in bytes); zero means OldSize + NewSize") \ "Initial heap size (in bytes); zero means use ergonomics") \
\ \
product(uintx, MaxHeapSize, ScaleForWordSize(96*M), \ product(uintx, MaxHeapSize, ScaleForWordSize(96*M), \
"Maximum heap size (in bytes)") \ "Maximum heap size (in bytes)") \
......
...@@ -61,6 +61,9 @@ public class WhiteBox { ...@@ -61,6 +61,9 @@ public class WhiteBox {
registerNatives(); registerNatives();
} }
// Arguments
public native void printHeapSizes();
// Memory // Memory
public native long getObjectAddress(Object o); public native long getObjectAddress(Object o);
public native int getHeapOopSize(); public native int getHeapOopSize();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册