-
Bug
-
Resolution: Fixed
-
P4
-
8, 9
-
b94
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8239521 | openjdk8u252 | Unassigned | P4 | Resolved | Fixed | b04 |
The following was reported by ivan.galkin@sap.com to the hotspot-gc-dev list:
I believe the calculation of max_eden_size which is needed to check the GC overhead in CMS is incorrect. Namely in concurrentMarkSweepGeneration.cpp the following expression is used:
size_t max_eden_size = _young_gen->max_capacity() - _young_gen->to()->capacity() - _young_gen->from()->capacity();
According to the implementation of DefNewGeneration::max_capacity() the expression can be unfolded as:
size_t max_eden_size = (“reserved size of young gen” – “size of survivor space”) – “size of survivor space” – “size of survivor space”;
So the value becomes too small (survival spaces are accounted 3 times!), which can lead to the following problems:
1. max_eden_size is too small and GC overhead is wrongfully recognized too early
2. max_eden_size == 0 (all young spaces have the same size; -XX:SurvivorRatio=1) and GC overhead is never happens (see implementation of AdaptiveSizePolicy::check_gc_overhead_limit:
a. max_eden_size == 0 leads to mem_free_eden_limit == 0;
b. free_in_eden < mem_free_eden_limit is always false, since both are unsigned integers and mem_free_eden_limit is 0)
I would therefore suggest the following fix (DefNewGeneration:: max_eden_size() already contains the correctly calculated capacity of eden):
diff -r f74b3ce62e1f src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp
--- a/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Fri Sep 04 17:33:56 2015 -0700
+++ b/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Mon Sep 07 18:08:39 2015 +0200
@@ -1563,9 +1563,7 @@
do_compaction_work(clear_all_soft_refs);
// Has the GC time limit been exceeded?
- size_t max_eden_size = _young_gen->max_capacity() -
- _young_gen->to()->capacity() -
- _young_gen->from()->capacity();
+ size_t max_eden_size = _young_gen->max_eden_size();
GCCause::Cause gc_cause = gch->gc_cause();
size_policy()->check_gc_overhead_limit(_young_gen->used(),
_young_gen->eden()->used(),
I believe the calculation of max_eden_size which is needed to check the GC overhead in CMS is incorrect. Namely in concurrentMarkSweepGeneration.cpp the following expression is used:
size_t max_eden_size = _young_gen->max_capacity() - _young_gen->to()->capacity() - _young_gen->from()->capacity();
According to the implementation of DefNewGeneration::max_capacity() the expression can be unfolded as:
size_t max_eden_size = (“reserved size of young gen” – “size of survivor space”) – “size of survivor space” – “size of survivor space”;
So the value becomes too small (survival spaces are accounted 3 times!), which can lead to the following problems:
1. max_eden_size is too small and GC overhead is wrongfully recognized too early
2. max_eden_size == 0 (all young spaces have the same size; -XX:SurvivorRatio=1) and GC overhead is never happens (see implementation of AdaptiveSizePolicy::check_gc_overhead_limit:
a. max_eden_size == 0 leads to mem_free_eden_limit == 0;
b. free_in_eden < mem_free_eden_limit is always false, since both are unsigned integers and mem_free_eden_limit is 0)
I would therefore suggest the following fix (DefNewGeneration:: max_eden_size() already contains the correctly calculated capacity of eden):
diff -r f74b3ce62e1f src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp
--- a/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Fri Sep 04 17:33:56 2015 -0700
+++ b/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Mon Sep 07 18:08:39 2015 +0200
@@ -1563,9 +1563,7 @@
do_compaction_work(clear_all_soft_refs);
// Has the GC time limit been exceeded?
- size_t max_eden_size = _young_gen->max_capacity() -
- _young_gen->to()->capacity() -
- _young_gen->from()->capacity();
+ size_t max_eden_size = _young_gen->max_eden_size();
GCCause::Cause gc_cause = gch->gc_cause();
size_policy()->check_gc_overhead_limit(_young_gen->used(),
_young_gen->eden()->used(),
- backported by
-
JDK-8239521 CMS: wrong max_eden_size for check_gc_overhead_limit
-
- Resolved
-