提交 57e8b3eb 编写于 作者: A amurillo

Merge

...@@ -414,3 +414,4 @@ c89630a122b43d0eabd78b74f6498a1c3cf04ca3 hs25.20-b00 ...@@ -414,3 +414,4 @@ c89630a122b43d0eabd78b74f6498a1c3cf04ca3 hs25.20-b00
df333ee12bba67e2e928f8ce1da37afd9bf95b48 jdk8-b124 df333ee12bba67e2e928f8ce1da37afd9bf95b48 jdk8-b124
412d3b5fe90e54c0ff9d9ac7374b98607c561d5a hs25.20-b01 412d3b5fe90e54c0ff9d9ac7374b98607c561d5a hs25.20-b01
4638c4d7ff106db0f29ef7f18b128dd7e69bc470 hs25.20-b02 4638c4d7ff106db0f29ef7f18b128dd7e69bc470 hs25.20-b02
e56d11f8cc2158d4280f80e56d196193349c150a hs25.20-b03
...@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2014 ...@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2014
HS_MAJOR_VER=25 HS_MAJOR_VER=25
HS_MINOR_VER=20 HS_MINOR_VER=20
HS_BUILD_NUMBER=02 HS_BUILD_NUMBER=03
JDK_MAJOR_VER=1 JDK_MAJOR_VER=1
JDK_MINOR_VER=8 JDK_MINOR_VER=8
......
/* /*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -1575,8 +1575,6 @@ void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) { ...@@ -1575,8 +1575,6 @@ void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) {
void void
G1CollectedHeap:: G1CollectedHeap::
resize_if_necessary_after_full_collection(size_t word_size) { resize_if_necessary_after_full_collection(size_t word_size) {
assert(MinHeapFreeRatio <= MaxHeapFreeRatio, "sanity check");
// Include the current allocation, if any, and bytes that will be // Include the current allocation, if any, and bytes that will be
// pre-allocated to support collections, as "used". // pre-allocated to support collections, as "used".
const size_t used_after_gc = used(); const size_t used_after_gc = used();
...@@ -5212,9 +5210,12 @@ private: ...@@ -5212,9 +5210,12 @@ private:
bool _process_symbols; bool _process_symbols;
int _symbols_processed; int _symbols_processed;
int _symbols_removed; int _symbols_removed;
bool _do_in_parallel;
public: public:
G1StringSymbolTableUnlinkTask(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols) : G1StringSymbolTableUnlinkTask(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols) :
AbstractGangTask("Par String/Symbol table unlink"), _is_alive(is_alive), AbstractGangTask("Par String/Symbol table unlink"), _is_alive(is_alive),
_do_in_parallel(G1CollectedHeap::use_parallel_gc_threads()),
_process_strings(process_strings), _strings_processed(0), _strings_removed(0), _process_strings(process_strings), _strings_processed(0), _strings_removed(0),
_process_symbols(process_symbols), _symbols_processed(0), _symbols_removed(0) { _process_symbols(process_symbols), _symbols_processed(0), _symbols_removed(0) {
...@@ -5229,16 +5230,16 @@ public: ...@@ -5229,16 +5230,16 @@ public:
} }
~G1StringSymbolTableUnlinkTask() { ~G1StringSymbolTableUnlinkTask() {
guarantee(!_process_strings || StringTable::parallel_claimed_index() >= _initial_string_table_size, guarantee(!_process_strings || !_do_in_parallel || StringTable::parallel_claimed_index() >= _initial_string_table_size,
err_msg("claim value "INT32_FORMAT" after unlink less than initial string table size "INT32_FORMAT, err_msg("claim value "INT32_FORMAT" after unlink less than initial string table size "INT32_FORMAT,
StringTable::parallel_claimed_index(), _initial_string_table_size)); StringTable::parallel_claimed_index(), _initial_string_table_size));
guarantee(!_process_strings || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size, guarantee(!_process_symbols || !_do_in_parallel || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size,
err_msg("claim value "INT32_FORMAT" after unlink less than initial symbol table size "INT32_FORMAT, err_msg("claim value "INT32_FORMAT" after unlink less than initial symbol table size "INT32_FORMAT,
SymbolTable::parallel_claimed_index(), _initial_symbol_table_size)); SymbolTable::parallel_claimed_index(), _initial_symbol_table_size));
} }
void work(uint worker_id) { void work(uint worker_id) {
if (G1CollectedHeap::use_parallel_gc_threads()) { if (_do_in_parallel) {
int strings_processed = 0; int strings_processed = 0;
int strings_removed = 0; int strings_removed = 0;
int symbols_processed = 0; int symbols_processed = 0;
......
/* /*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -86,13 +86,26 @@ public: ...@@ -86,13 +86,26 @@ public:
#define G1_PARTIAL_ARRAY_MASK 0x2 #define G1_PARTIAL_ARRAY_MASK 0x2
template <class T> inline bool has_partial_array_mask(T* ref) { inline bool has_partial_array_mask(oop* ref) {
return ((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) == G1_PARTIAL_ARRAY_MASK; return ((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) == G1_PARTIAL_ARRAY_MASK;
} }
template <class T> inline T* set_partial_array_mask(T obj) { // We never encode partial array oops as narrowOop*, so return false immediately.
// This allows the compiler to create optimized code when popping references from
// the work queue.
inline bool has_partial_array_mask(narrowOop* ref) {
assert(((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) != G1_PARTIAL_ARRAY_MASK, "Partial array oop reference encoded as narrowOop*");
return false;
}
// Only implement set_partial_array_mask() for regular oops, not for narrowOops.
// We always encode partial arrays as regular oop, to allow the
// specialization for has_partial_array_mask() for narrowOops above.
// This means that unintentional use of this method with narrowOops are caught
// by the compiler.
inline oop* set_partial_array_mask(oop obj) {
assert(((uintptr_t)(void *)obj & G1_PARTIAL_ARRAY_MASK) == 0, "Information loss!"); assert(((uintptr_t)(void *)obj & G1_PARTIAL_ARRAY_MASK) == 0, "Information loss!");
return (T*) ((uintptr_t)(void *)obj | G1_PARTIAL_ARRAY_MASK); return (oop*) ((uintptr_t)(void *)obj | G1_PARTIAL_ARRAY_MASK);
} }
template <class T> inline oop clear_partial_array_mask(T* ref) { template <class T> inline oop clear_partial_array_mask(T* ref) {
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
*/ */
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
#include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
#include "gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp" #include "gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp" #include "gc_implementation/parallelScavenge/psScavenge.hpp"
...@@ -76,6 +77,38 @@ PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size, ...@@ -76,6 +77,38 @@ PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size,
_old_gen_policy_is_ready = false; _old_gen_policy_is_ready = false;
} }
size_t PSAdaptiveSizePolicy::calculate_free_based_on_live(size_t live, uintx ratio_as_percentage) {
// We want to calculate how much free memory there can be based on the
// amount of live data currently in the old gen. Using the formula:
// ratio * (free + live) = free
// Some equation solving later we get:
// free = (live * ratio) / (1 - ratio)
const double ratio = ratio_as_percentage / 100.0;
const double ratio_inverse = 1.0 - ratio;
const double tmp = live * ratio;
size_t free = (size_t)(tmp / ratio_inverse);
return free;
}
size_t PSAdaptiveSizePolicy::calculated_old_free_size_in_bytes() const {
size_t free_size = (size_t)(_promo_size + avg_promoted()->padded_average());
size_t live = ParallelScavengeHeap::heap()->old_gen()->used_in_bytes();
if (MinHeapFreeRatio != 0) {
size_t min_free = calculate_free_based_on_live(live, MinHeapFreeRatio);
free_size = MAX2(free_size, min_free);
}
if (MaxHeapFreeRatio != 100) {
size_t max_free = calculate_free_based_on_live(live, MaxHeapFreeRatio);
free_size = MIN2(max_free, free_size);
}
return free_size;
}
void PSAdaptiveSizePolicy::major_collection_begin() { void PSAdaptiveSizePolicy::major_collection_begin() {
// Update the interval time // Update the interval time
_major_timer.stop(); _major_timer.stop();
...@@ -1292,3 +1325,18 @@ bool PSAdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st) ...@@ -1292,3 +1325,18 @@ bool PSAdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st)
st, st,
PSScavenge::tenuring_threshold()); PSScavenge::tenuring_threshold());
} }
#ifndef PRODUCT
void TestOldFreeSpaceCalculation_test() {
assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 20) == 25, "Calculation of free memory failed");
assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 50) == 100, "Calculation of free memory failed");
assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 60) == 150, "Calculation of free memory failed");
assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 75) == 300, "Calculation of free memory failed");
assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 20) == 100, "Calculation of free memory failed");
assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 50) == 400, "Calculation of free memory failed");
assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 60) == 600, "Calculation of free memory failed");
assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 75) == 1200, "Calculation of free memory failed");
}
#endif /* !PRODUCT */
...@@ -240,7 +240,6 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { ...@@ -240,7 +240,6 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
void major_collection_begin(); void major_collection_begin();
void major_collection_end(size_t amount_live, GCCause::Cause gc_cause); void major_collection_end(size_t amount_live, GCCause::Cause gc_cause);
//
void tenured_allocation(size_t size) { void tenured_allocation(size_t size) {
_avg_pretenured->sample(size); _avg_pretenured->sample(size);
} }
...@@ -248,9 +247,9 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { ...@@ -248,9 +247,9 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
// Accessors // Accessors
// NEEDS_CLEANUP should use sizes.hpp // NEEDS_CLEANUP should use sizes.hpp
size_t calculated_old_free_size_in_bytes() const { static size_t calculate_free_based_on_live(size_t live, uintx ratio_as_percentage);
return (size_t)(_promo_size + avg_promoted()->padded_average());
} size_t calculated_old_free_size_in_bytes() const;
size_t average_old_live_in_bytes() const { size_t average_old_live_in_bytes() const {
return (size_t) avg_old_live()->average(); return (size_t) avg_old_live()->average();
......
...@@ -529,8 +529,19 @@ bool PSScavenge::invoke_no_policy() { ...@@ -529,8 +529,19 @@ bool PSScavenge::invoke_no_policy() {
counters->update_survivor_overflowed(_survivor_overflow); counters->update_survivor_overflowed(_survivor_overflow);
} }
size_t max_young_size = young_gen->max_size();
// Deciding a free ratio in the young generation is tricky, so if
// MinHeapFreeRatio or MaxHeapFreeRatio are in use (implicating
// that the old generation size may have been limited because of them) we
// should then limit our young generation size using NewRatio to have it
// follow the old generation size.
if (MinHeapFreeRatio != 0 || MaxHeapFreeRatio != 100) {
max_young_size = MIN2(old_gen->capacity_in_bytes() / NewRatio, young_gen->max_size());
}
size_t survivor_limit = size_t survivor_limit =
size_policy->max_survivor_size(young_gen->max_size()); size_policy->max_survivor_size(max_young_size);
_tenuring_threshold = _tenuring_threshold =
size_policy->compute_survivor_space_size_and_threshold( size_policy->compute_survivor_space_size_and_threshold(
_survivor_overflow, _survivor_overflow,
...@@ -553,8 +564,7 @@ bool PSScavenge::invoke_no_policy() { ...@@ -553,8 +564,7 @@ bool PSScavenge::invoke_no_policy() {
// Do call at minor collections? // Do call at minor collections?
// Don't check if the size_policy is ready at this // Don't check if the size_policy is ready at this
// level. Let the size_policy check that internally. // level. Let the size_policy check that internally.
if (UseAdaptiveSizePolicy && if (UseAdaptiveGenerationSizePolicyAtMinorCollection &&
UseAdaptiveGenerationSizePolicyAtMinorCollection &&
((gc_cause != GCCause::_java_lang_system_gc) || ((gc_cause != GCCause::_java_lang_system_gc) ||
UseAdaptiveSizePolicyWithSystemGC)) { UseAdaptiveSizePolicyWithSystemGC)) {
...@@ -568,7 +578,7 @@ bool PSScavenge::invoke_no_policy() { ...@@ -568,7 +578,7 @@ bool PSScavenge::invoke_no_policy() {
size_t eden_live = young_gen->eden_space()->used_in_bytes(); size_t eden_live = young_gen->eden_space()->used_in_bytes();
size_t cur_eden = young_gen->eden_space()->capacity_in_bytes(); size_t cur_eden = young_gen->eden_space()->capacity_in_bytes();
size_t max_old_gen_size = old_gen->max_gen_size(); size_t max_old_gen_size = old_gen->max_gen_size();
size_t max_eden_size = young_gen->max_size() - size_t max_eden_size = max_young_size -
young_gen->from_space()->capacity_in_bytes() - young_gen->from_space()->capacity_in_bytes() -
young_gen->to_space()->capacity_in_bytes(); young_gen->to_space()->capacity_in_bytes();
......
...@@ -127,7 +127,7 @@ class PSYoungGen : public CHeapObj<mtGC> { ...@@ -127,7 +127,7 @@ class PSYoungGen : public CHeapObj<mtGC> {
void adjust_pointers(); void adjust_pointers();
void compact(); void compact();
// Called during/after gc // Called during/after GC
void swap_spaces(); void swap_spaces();
// Resize generation using suggested free space size and survivor size // Resize generation using suggested free space size and survivor size
...@@ -146,14 +146,14 @@ class PSYoungGen : public CHeapObj<mtGC> { ...@@ -146,14 +146,14 @@ class PSYoungGen : public CHeapObj<mtGC> {
size_t free_in_words() const; size_t free_in_words() const;
// The max this generation can grow to // The max this generation can grow to
size_t max_size() const { return _reserved.byte_size(); } size_t max_size() const { return _reserved.byte_size(); }
// The max this generation can grow to if the boundary between // The max this generation can grow to if the boundary between
// the generations are allowed to move. // the generations are allowed to move.
size_t gen_size_limit() const { return _max_gen_size; } size_t gen_size_limit() const { return _max_gen_size; }
bool is_maximal_no_gc() const { bool is_maximal_no_gc() const {
return true; // never expands except at a GC return true; // Never expands except at a GC
} }
// Allocation // Allocation
......
...@@ -5061,6 +5061,7 @@ void TestVirtualSpace_test(); ...@@ -5061,6 +5061,7 @@ void TestVirtualSpace_test();
void TestMetaspaceAux_test(); void TestMetaspaceAux_test();
void TestMetachunk_test(); void TestMetachunk_test();
void TestVirtualSpaceNode_test(); void TestVirtualSpaceNode_test();
void TestOldFreeSpaceCalculation_test();
#if INCLUDE_ALL_GCS #if INCLUDE_ALL_GCS
void TestG1BiasedArray_test(); void TestG1BiasedArray_test();
#endif #endif
...@@ -5081,6 +5082,7 @@ void execute_internal_vm_tests() { ...@@ -5081,6 +5082,7 @@ void execute_internal_vm_tests() {
run_unit_test(QuickSort::test_quick_sort()); run_unit_test(QuickSort::test_quick_sort());
run_unit_test(AltHashing::test_alt_hash()); run_unit_test(AltHashing::test_alt_hash());
run_unit_test(test_loggc_filename()); run_unit_test(test_loggc_filename());
run_unit_test(TestOldFreeSpaceCalculation_test());
#if INCLUDE_VM_STRUCTS #if INCLUDE_VM_STRUCTS
run_unit_test(VMStructs::test()); run_unit_test(VMStructs::test());
#endif #endif
......
...@@ -1569,6 +1569,16 @@ void Arguments::set_parallel_gc_flags() { ...@@ -1569,6 +1569,16 @@ void Arguments::set_parallel_gc_flags() {
vm_exit(1); vm_exit(1);
} }
if (UseAdaptiveSizePolicy) {
// We don't want to limit adaptive heap sizing's freedom to adjust the heap
// unless the user actually sets these flags.
if (FLAG_IS_DEFAULT(MinHeapFreeRatio)) {
FLAG_SET_DEFAULT(MinHeapFreeRatio, 0);
}
if (FLAG_IS_DEFAULT(MaxHeapFreeRatio)) {
FLAG_SET_DEFAULT(MaxHeapFreeRatio, 100);
}
}
// If InitialSurvivorRatio or MinSurvivorRatio were not specified, but the // If InitialSurvivorRatio or MinSurvivorRatio were not specified, but the
// SurvivorRatio has been set, reset their default values to SurvivorRatio + // SurvivorRatio has been set, reset their default values to SurvivorRatio +
...@@ -1844,7 +1854,7 @@ bool Arguments::verify_min_value(intx val, intx min, const char* name) { ...@@ -1844,7 +1854,7 @@ bool Arguments::verify_min_value(intx val, intx min, const char* name) {
} }
bool Arguments::verify_percentage(uintx value, const char* name) { bool Arguments::verify_percentage(uintx value, const char* name) {
if (value <= 100) { if (is_percentage(value)) {
return true; return true;
} }
jio_fprintf(defaultStream::error_stream(), jio_fprintf(defaultStream::error_stream(),
...@@ -1932,6 +1942,34 @@ bool is_filename_valid(const char *file_name) { ...@@ -1932,6 +1942,34 @@ bool is_filename_valid(const char *file_name) {
return count_p < 2 && count_t < 2; return count_p < 2 && count_t < 2;
} }
bool Arguments::verify_MinHeapFreeRatio(FormatBuffer<80>& err_msg, uintx min_heap_free_ratio) {
if (!is_percentage(min_heap_free_ratio)) {
err_msg.print("MinHeapFreeRatio must have a value between 0 and 100");
return false;
}
if (min_heap_free_ratio > MaxHeapFreeRatio) {
err_msg.print("MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or "
"equal to MaxHeapFreeRatio (" UINTX_FORMAT ")", min_heap_free_ratio,
MaxHeapFreeRatio);
return false;
}
return true;
}
bool Arguments::verify_MaxHeapFreeRatio(FormatBuffer<80>& err_msg, uintx max_heap_free_ratio) {
if (!is_percentage(max_heap_free_ratio)) {
err_msg.print("MaxHeapFreeRatio must have a value between 0 and 100");
return false;
}
if (max_heap_free_ratio < MinHeapFreeRatio) {
err_msg.print("MaxHeapFreeRatio (" UINTX_FORMAT ") must be greater than or "
"equal to MinHeapFreeRatio (" UINTX_FORMAT ")", max_heap_free_ratio,
MinHeapFreeRatio);
return false;
}
return true;
}
// Check consistency of GC selection // Check consistency of GC selection
bool Arguments::check_gc_consistency() { bool Arguments::check_gc_consistency() {
check_gclog_consistency(); check_gclog_consistency();
...@@ -2037,8 +2075,6 @@ bool Arguments::check_vm_args_consistency() { ...@@ -2037,8 +2075,6 @@ bool Arguments::check_vm_args_consistency() {
status = status && verify_interval(AdaptiveSizePolicyWeight, 0, 100, status = status && verify_interval(AdaptiveSizePolicyWeight, 0, 100,
"AdaptiveSizePolicyWeight"); "AdaptiveSizePolicyWeight");
status = status && verify_percentage(ThresholdTolerance, "ThresholdTolerance"); status = status && verify_percentage(ThresholdTolerance, "ThresholdTolerance");
status = status && verify_percentage(MinHeapFreeRatio, "MinHeapFreeRatio");
status = status && verify_percentage(MaxHeapFreeRatio, "MaxHeapFreeRatio");
// Divide by bucket size to prevent a large size from causing rollover when // Divide by bucket size to prevent a large size from causing rollover when
// calculating amount of memory needed to be allocated for the String table. // calculating amount of memory needed to be allocated for the String table.
...@@ -2048,15 +2084,19 @@ bool Arguments::check_vm_args_consistency() { ...@@ -2048,15 +2084,19 @@ bool Arguments::check_vm_args_consistency() {
status = status && verify_interval(SymbolTableSize, minimumSymbolTableSize, status = status && verify_interval(SymbolTableSize, minimumSymbolTableSize,
(max_uintx / SymbolTable::bucket_size()), "SymbolTable size"); (max_uintx / SymbolTable::bucket_size()), "SymbolTable size");
if (MinHeapFreeRatio > MaxHeapFreeRatio) { {
jio_fprintf(defaultStream::error_stream(), // Using "else if" below to avoid printing two error messages if min > max.
"MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or " // This will also prevent us from reporting both min>100 and max>100 at the
"equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n", // same time, but that is less annoying than printing two identical errors IMHO.
MinHeapFreeRatio, MaxHeapFreeRatio); FormatBuffer<80> err_msg("");
status = false; if (!verify_MinHeapFreeRatio(err_msg, MinHeapFreeRatio)) {
jio_fprintf(defaultStream::error_stream(), "%s\n", err_msg.buffer());
status = false;
} else if (!verify_MaxHeapFreeRatio(err_msg, MaxHeapFreeRatio)) {
jio_fprintf(defaultStream::error_stream(), "%s\n", err_msg.buffer());
status = false;
}
} }
// Keeping the heap 100% free is hard ;-) so limit it to 99%.
MinHeapFreeRatio = MIN2(MinHeapFreeRatio, (uintx) 99);
// Min/MaxMetaspaceFreeRatio // Min/MaxMetaspaceFreeRatio
status = status && verify_percentage(MinMetaspaceFreeRatio, "MinMetaspaceFreeRatio"); status = status && verify_percentage(MinMetaspaceFreeRatio, "MinMetaspaceFreeRatio");
...@@ -2689,7 +2729,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, ...@@ -2689,7 +2729,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
} else if (match_option(option, "-Xmaxf", &tail)) { } else if (match_option(option, "-Xmaxf", &tail)) {
char* err; char* err;
int maxf = (int)(strtod(tail, &err) * 100); int maxf = (int)(strtod(tail, &err) * 100);
if (*err != '\0' || maxf < 0 || maxf > 100) { if (*err != '\0' || *tail == '\0' || maxf < 0 || maxf > 100) {
jio_fprintf(defaultStream::error_stream(), jio_fprintf(defaultStream::error_stream(),
"Bad max heap free percentage size: %s\n", "Bad max heap free percentage size: %s\n",
option->optionString); option->optionString);
...@@ -2701,7 +2741,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, ...@@ -2701,7 +2741,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
} else if (match_option(option, "-Xminf", &tail)) { } else if (match_option(option, "-Xminf", &tail)) {
char* err; char* err;
int minf = (int)(strtod(tail, &err) * 100); int minf = (int)(strtod(tail, &err) * 100);
if (*err != '\0' || minf < 0 || minf > 100) { if (*err != '\0' || *tail == '\0' || minf < 0 || minf > 100) {
jio_fprintf(defaultStream::error_stream(), jio_fprintf(defaultStream::error_stream(),
"Bad min heap free percentage size: %s\n", "Bad min heap free percentage size: %s\n",
option->optionString); option->optionString);
...@@ -3646,9 +3686,9 @@ jint Arguments::apply_ergo() { ...@@ -3646,9 +3686,9 @@ jint Arguments::apply_ergo() {
// Set per-collector flags // Set per-collector flags
if (UseParallelGC || UseParallelOldGC) { if (UseParallelGC || UseParallelOldGC) {
set_parallel_gc_flags(); set_parallel_gc_flags();
} else if (UseConcMarkSweepGC) { // should be done before ParNew check below } else if (UseConcMarkSweepGC) { // Should be done before ParNew check below
set_cms_and_parnew_gc_flags(); set_cms_and_parnew_gc_flags();
} else if (UseParNewGC) { // skipped if CMS is set above } else if (UseParNewGC) { // Skipped if CMS is set above
set_parnew_gc_flags(); set_parnew_gc_flags();
} else if (UseG1GC) { } else if (UseG1GC) {
set_g1_gc_flags(); set_g1_gc_flags();
...@@ -3662,6 +3702,10 @@ jint Arguments::apply_ergo() { ...@@ -3662,6 +3702,10 @@ jint Arguments::apply_ergo() {
" using -XX:ParallelGCThreads=N"); " using -XX:ParallelGCThreads=N");
} }
} }
if (MinHeapFreeRatio == 100) {
// Keeping the heap 100% free is hard ;-) so limit it to 99%.
FLAG_SET_ERGO(uintx, MinHeapFreeRatio, 99);
}
#else // INCLUDE_ALL_GCS #else // INCLUDE_ALL_GCS
assert(verify_serial_gc_flags(), "SerialGC unset"); assert(verify_serial_gc_flags(), "SerialGC unset");
#endif // INCLUDE_ALL_GCS #endif // INCLUDE_ALL_GCS
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "runtime/java.hpp" #include "runtime/java.hpp"
#include "runtime/perfData.hpp" #include "runtime/perfData.hpp"
#include "utilities/debug.hpp"
#include "utilities/top.hpp" #include "utilities/top.hpp"
// Arguments parses the command line and recognizes options // Arguments parses the command line and recognizes options
...@@ -370,11 +371,16 @@ class Arguments : AllStatic { ...@@ -370,11 +371,16 @@ class Arguments : AllStatic {
static jint parse_vm_init_args(const JavaVMInitArgs* args); static jint parse_vm_init_args(const JavaVMInitArgs* args);
static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, SysClassPath* scp_p, bool* scp_assembly_required_p, Flag::Flags origin); static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, SysClassPath* scp_p, bool* scp_assembly_required_p, Flag::Flags origin);
static jint finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_required); static jint finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_required);
static bool is_bad_option(const JavaVMOption* option, jboolean ignore, static bool is_bad_option(const JavaVMOption* option, jboolean ignore, const char* option_type);
const char* option_type);
static bool is_bad_option(const JavaVMOption* option, jboolean ignore) { static bool is_bad_option(const JavaVMOption* option, jboolean ignore) {
return is_bad_option(option, ignore, NULL); return is_bad_option(option, ignore, NULL);
} }
static bool is_percentage(uintx val) {
return val <= 100;
}
static bool verify_interval(uintx val, uintx min, static bool verify_interval(uintx val, uintx min,
uintx max, const char* name); uintx max, const char* name);
static bool verify_min_value(intx val, intx min, const char* name); static bool verify_min_value(intx val, intx min, const char* name);
...@@ -440,6 +446,15 @@ class Arguments : AllStatic { ...@@ -440,6 +446,15 @@ class Arguments : AllStatic {
static jint apply_ergo(); static jint apply_ergo();
// Adjusts the arguments after the OS have adjusted the arguments // Adjusts the arguments after the OS have adjusted the arguments
static jint adjust_after_os(); static jint adjust_after_os();
// Verifies that the given value will fit as a MinHeapFreeRatio. If not, an error
// message is returned in the provided buffer.
static bool verify_MinHeapFreeRatio(FormatBuffer<80>& err_msg, uintx min_heap_free_ratio);
// Verifies that the given value will fit as a MaxHeapFreeRatio. If not, an error
// message is returned in the provided buffer.
static bool verify_MaxHeapFreeRatio(FormatBuffer<80>& err_msg, uintx max_heap_free_ratio);
// Check for consistency in the selection of the garbage collector. // Check for consistency in the selection of the garbage collector.
static bool check_gc_consistency(); static bool check_gc_consistency();
static void check_deprecated_gcs(); static void check_deprecated_gcs();
......
...@@ -3133,15 +3133,15 @@ class CommandLineFlags { ...@@ -3133,15 +3133,15 @@ class CommandLineFlags {
"Maximum size of class area in Metaspace when compressed " \ "Maximum size of class area in Metaspace when compressed " \
"class pointers are used") \ "class pointers are used") \
\ \
product(uintx, MinHeapFreeRatio, 40, \ manageable(uintx, MinHeapFreeRatio, 40, \
"The minimum percentage of heap free after GC to avoid expansion."\ "The minimum percentage of heap free after GC to avoid expansion."\
" For most GCs this applies to the old generation. In G1 it" \ " For most GCs this applies to the old generation. In G1 and" \
" applies to the whole heap. Not supported by ParallelGC.") \ " ParallelGC it applies to the whole heap.") \
\ \
product(uintx, MaxHeapFreeRatio, 70, \ manageable(uintx, MaxHeapFreeRatio, 70, \
"The maximum percentage of heap free after GC to avoid shrinking."\ "The maximum percentage of heap free after GC to avoid shrinking."\
" For most GCs this applies to the old generation. In G1 it" \ " For most GCs this applies to the old generation. In G1 and" \
" applies to the whole heap. Not supported by ParallelGC.") \ " ParallelGC it applies to the whole heap.") \
\ \
product(intx, SoftRefLRUPolicyMSPerMB, 1000, \ product(intx, SoftRefLRUPolicyMSPerMB, 1000, \
"Number of milliseconds per MB of free space in the heap") \ "Number of milliseconds per MB of free space in the heap") \
......
...@@ -282,6 +282,20 @@ static jint set_uintx_flag(const char* name, AttachOperation* op, outputStream* ...@@ -282,6 +282,20 @@ static jint set_uintx_flag(const char* name, AttachOperation* op, outputStream*
return JNI_ERR; return JNI_ERR;
} }
} }
if (strncmp(name, "MaxHeapFreeRatio", 17) == 0) {
FormatBuffer<80> err_msg("");
if (!Arguments::verify_MaxHeapFreeRatio(err_msg, value)) {
out->print_cr(err_msg.buffer());
return JNI_ERR;
}
} else if (strncmp(name, "MinHeapFreeRatio", 17) == 0) {
FormatBuffer<80> err_msg("");
if (!Arguments::verify_MinHeapFreeRatio(err_msg, value)) {
out->print_cr(err_msg.buffer());
return JNI_ERR;
}
}
bool res = CommandLineFlags::uintxAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND); bool res = CommandLineFlags::uintxAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND);
if (! res) { if (! res) {
out->print_cr("setting flag %s failed", name); out->print_cr("setting flag %s failed", name);
......
...@@ -1830,6 +1830,18 @@ JVM_ENTRY(void, jmm_SetVMGlobal(JNIEnv *env, jstring flag_name, jvalue new_value ...@@ -1830,6 +1830,18 @@ JVM_ENTRY(void, jmm_SetVMGlobal(JNIEnv *env, jstring flag_name, jvalue new_value
succeed = CommandLineFlags::intxAtPut(name, &ivalue, Flag::MANAGEMENT); succeed = CommandLineFlags::intxAtPut(name, &ivalue, Flag::MANAGEMENT);
} else if (flag->is_uintx()) { } else if (flag->is_uintx()) {
uintx uvalue = (uintx)new_value.j; uintx uvalue = (uintx)new_value.j;
if (strncmp(name, "MaxHeapFreeRatio", 17) == 0) {
FormatBuffer<80> err_msg("");
if (!Arguments::verify_MaxHeapFreeRatio(err_msg, uvalue)) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg.buffer());
}
} else if (strncmp(name, "MinHeapFreeRatio", 17) == 0) {
FormatBuffer<80> err_msg("");
if (!Arguments::verify_MinHeapFreeRatio(err_msg, uvalue)) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg.buffer());
}
}
succeed = CommandLineFlags::uintxAtPut(name, &uvalue, Flag::MANAGEMENT); succeed = CommandLineFlags::uintxAtPut(name, &uvalue, Flag::MANAGEMENT);
} else if (flag->is_uint64_t()) { } else if (flag->is_uint64_t()) {
uint64_t uvalue = (uint64_t)new_value.j; uint64_t uvalue = (uint64_t)new_value.j;
......
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test TestVerifySilently.java
* @key gc
* @bug 8032771
* @summary Test silent verification.
* @library /testlibrary
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.ProcessTools;
import java.util.ArrayList;
import java.util.Collections;
class RunSystemGC {
public static void main(String args[]) throws Exception {
System.gc();
}
}
public class TestVerifySilently {
private static String[] getTestJavaOpts() {
String testVmOptsStr = System.getProperty("test.java.opts");
if (!testVmOptsStr.isEmpty()) {
return testVmOptsStr.split(" ");
} else {
return new String[] {};
}
}
private static OutputAnalyzer runTest(boolean verifySilently) throws Exception {
ArrayList<String> vmOpts = new ArrayList();
Collections.addAll(vmOpts, getTestJavaOpts());
Collections.addAll(vmOpts, new String[] {"-XX:+UnlockDiagnosticVMOptions",
"-XX:+VerifyDuringStartup",
"-XX:+VerifyBeforeGC",
"-XX:+VerifyAfterGC",
"-XX:" + (verifySilently ? "+":"-") + "VerifySilently",
RunSystemGC.class.getName()});
ProcessBuilder pb =
ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
System.out.println("Output:\n" + output.getOutput());
return output;
}
public static void main(String args[]) throws Exception {
OutputAnalyzer output;
output = runTest(false);
output.shouldContain("[Verifying");
output.shouldHaveExitValue(0);
output = runTest(true);
output.shouldNotContain("[Verifying");
output.shouldHaveExitValue(0);
}
}
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
/* /*
* @test * @test
* @key nmt * @key nmt
* @summary Running with NMT detail should not result in an error or warning * @summary Running with NMT detail should not result in an error
* @library /testlibrary * @library /testlibrary
*/ */
...@@ -39,7 +39,6 @@ public class CommandLineDetail { ...@@ -39,7 +39,6 @@ public class CommandLineDetail {
"-version"); "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotContain("error"); output.shouldNotContain("error");
output.shouldNotContain("warning");
output.shouldHaveExitValue(0); output.shouldHaveExitValue(0);
} }
} }
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
/* /*
* @test * @test
* @key nmt * @key nmt
* @summary Running with NMT summary should not result in an error or warning * @summary Running with NMT summary should not result in an error
* @library /testlibrary * @library /testlibrary
*/ */
...@@ -39,7 +39,6 @@ public class CommandLineSummary { ...@@ -39,7 +39,6 @@ public class CommandLineSummary {
"-version"); "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotContain("error"); output.shouldNotContain("error");
output.shouldNotContain("warning");
output.shouldHaveExitValue(0); output.shouldHaveExitValue(0);
} }
} }
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
/* /*
* @test * @test
* @key nmt * @key nmt
* @summary Turning off NMT should not result in an error or warning * @summary Turning off NMT should not result in an error
* @library /testlibrary * @library /testlibrary
*/ */
...@@ -38,7 +38,6 @@ public class CommandLineTurnOffNMT { ...@@ -38,7 +38,6 @@ public class CommandLineTurnOffNMT {
"-version"); "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotContain("error"); output.shouldNotContain("error");
output.shouldNotContain("warning");
output.shouldHaveExitValue(0); output.shouldHaveExitValue(0);
} }
} }
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -64,7 +64,6 @@ public class PrintNMTStatistics { ...@@ -64,7 +64,6 @@ public class PrintNMTStatistics {
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("Java Heap (reserved="); output.shouldContain("Java Heap (reserved=");
output.shouldNotContain("error"); output.shouldNotContain("error");
output.shouldNotContain("warning");
output.shouldHaveExitValue(0); output.shouldHaveExitValue(0);
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册