1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
void
DefNewGeneration::collect(
bool
full,
bool
clear_all_soft_refs,
size_t
size,
bool
is_tlab) {
...
if
(!collection_attempt_is_safe()) {
gch->set_incremental_collection_will_fail();
return
;
}
...
}
bool
DefNewGeneration::collection_attempt_is_safe() {
if
(!to()->is_empty()) {
return
false
;
}
if
(_next_gen == NULL) {
GenCollectedHeap* gch = GenCollectedHeap::heap();
_next_gen = gch->next_gen(
this
);
assert
(_next_gen != NULL,
"This must be the youngest gen, and not the only gen"
);
}
const
double
evacuation_ratio = MaxLiveObjectEvacuationRatio / 100.0;
size_t
worst_case_evacuation = (
size_t
)(used() * evacuation_ratio);
// 这里的_next_gen也就是旧生代了,下面贴出旧生代对应的代码
return
_next_gen->promotion_attempt_is_safe(worst_case_evacuation,
HandlePromotionFailure);
}
bool
TenuredGeneration::promotion_attempt_is_safe(
size_t
max_promotion_in_bytes,
bool
younger_handles_promotion_failure)
const
{
bool
result = max_contiguous_available() >= max_promotion_in_bytes;
if
(younger_handles_promotion_failure && !result) {
result = max_contiguous_available() >=
(
size_t
) gc_stats()->avg_promoted()->padded_average();
if
(PrintGC && Verbose && result) {
gclog_or_tty->print_cr(
"TenuredGeneration::promotion_attempt_is_safe"
" contiguous_available: "
SIZE_FORMAT
" avg_promoted: "
SIZE_FORMAT,
max_contiguous_available(),
gc_stats()->avg_promoted()->padded_average());
}
}
else
{
if
(PrintGC && Verbose) {
gclog_or_tty->print_cr(
"TenuredGeneration::promotion_attempt_is_safe"
" contiguous_available: "
SIZE_FORMAT
" promotion_in_bytes: "
SIZE_FORMAT,
max_contiguous_available(), max_promotion_in_bytes);
}
}
return
result;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
void
GenCollectedHeap::do_collection(
bool
full,
bool
clear_all_soft_refs,
size_t
size,
bool
is_tlab,
int
max_level) {
...
// 在当前场景下,传入的full为false,因此complete为false
bool
complete = full && (max_level == (n_gens()-1));
const
char
* gc_cause_str =
"GC "
;
if
(complete) {
GCCause::Cause cause = gc_cause();
if
(cause == GCCause::_java_lang_system_gc) {
gc_cause_str =
"Full GC (System) "
;
}
else
{
gc_cause_str =
"Full GC "
;
}
}
...
for
(
int
i = starting_level; i <= max_level; i++) {
if
(_gens[i]->should_collect(full, size, is_tlab)) {
...
// Determine if allocation request was met.
if
(size > 0) {
if
(!is_tlab || _gens[i]->supports_tlab_allocation()) {
if
(size*HeapWordSize <= _gens[i]->unsafe_max_alloc_nogc()) {
size = 0;
}
}
}
...
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
bool
TenuredGeneration::should_collect(
bool
full,
size_t
size,
bool
is_tlab) {
// This should be one big conditional or (||), but I want to be able to tell
// why it returns what it returns (without re-evaluating the conditionals
// in case they aren't idempotent), so I'm doing it this way.
// DeMorgan says it's okay.
bool
result =
false
;
// 因为full是false,因此进入不了这里
if
(!result && full) {
result =
true
;
if
(PrintGC && Verbose) {
gclog_or_tty->print_cr(
"TenuredGeneration::should_collect: because"
" full"
);
}
}
if
(!result && should_allocate(size, is_tlab)) {
result =
true
;
if
(PrintGC && Verbose) {
gclog_or_tty->print_cr(
"TenuredGeneration::should_collect: because"
" should_allocate("
SIZE_FORMAT
")"
,
size);
}
}
// If we don't have very much free space.
// XXX: 10000 should be a percentage of the capacity!!!
if
(!result &&
free
() < 10000) {
result =
true
;
if
(PrintGC && Verbose) {
gclog_or_tty->print_cr(
"TenuredGeneration::should_collect: because"
" free(): "
SIZE_FORMAT,
free
());
}
}
// If we had to expand to accomodate promotions from younger generations
if
(!result && _capacity_at_prologue < capacity()) {
result =
true
;
if
(PrintGC && Verbose) {
gclog_or_tty->print_cr(
"TenuredGeneration::should_collect: because"
"_capacity_at_prologue: "
SIZE_FORMAT
" < capacity(): "
SIZE_FORMAT,
_capacity_at_prologue, capacity());
}
}
return
result;
}
virtual
bool
should_allocate(
size_t
word_size,
bool
is_tlab) {
bool
result =
false
;
// 32 bit上BitsPerSize_t为32,64 bit上为64, LogHeapWordSize在32 bit为2,64 bit为3
size_t
overflow_limit = (
size_t
)1 << (BitsPerSize_t - LogHeapWordSize);
if
(!is_tlab || supports_tlab_allocation()) {
result = (word_size > 0) && (word_size < overflow_limit);
}
return
result;
}
|