DefNewGeneration::collect

void DefNewGeneration::collect(bool   full,
bool clear_all_soft_refs, // todo soft
size_t size,
bool is_tlab) {

......
// 返回true: to()空间空闲 && 某个代的剩余空间能够容下本次垃圾回收需要的空间
if (!collection_attempt_is_safe()) {
if (Verbose && PrintGCDetails) {
gclog_or_tty->print(" :: Collection attempt not safe :: ");
} // /告诉内存堆管理器不要再考虑增量式GC(Minor Gc),因为一定会失败
gch->set_incremental_collection_failed(); // Slight lie: we did not even attempt one
return;
}

......

}

collection_attempt_is_safe()

// todo gc   DefNewGeneration正式进行Gc前会先检测一下本次Minor Gc是否安全,如果不安全则直接放弃本次Gc,检查策略是 1. To区空闲  2. 下一个内存代的可用空间能够容纳当前内存代的所有对象(用于对象升级)
bool DefNewGeneration::collection_attempt_is_safe() {
if (!to()->is_empty()) { // To区空闲
if (Verbose && PrintGCDetails) {
gclog_or_tty->print(" :: to is not empty :: ");
}
return false;
}
if (_next_gen == NULL) {
GenCollectedHeap* gch = GenCollectedHeap::heap();
_next_gen = gch->next_gen(this);
}
// 下一个内存代的可用空间能够容纳当前内存代的所有对象(用于对象升级)
return _next_gen->promotion_attempt_is_safe(used());
}

Generation::promotion_attempt_is_safe

//true:空间够了 false:空间不够
bool Generation::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const {
size_t available = max_contiguous_available(); // 剩余可用内存(取可用空间多的代的剩余空间)
bool res = (available >= max_promotion_in_bytes); // max_promotion_in_bytes:本次垃圾回收需要最大空间
if (PrintGC && Verbose) {
gclog_or_tty->print_cr(
"Generation: promo attempt is%s safe: available("SIZE_FORMAT") %s max_promo("SIZE_FORMAT")",
res? "":" not", available, res? ">=":"<",
max_promotion_in_bytes);
}
return res; // true:空间够了 false:空间不够
}

Generation::max_contiguous_available

//  max取可用空间多的Generation
size_t Generation::max_contiguous_available() const {
// The largest number of contiguous free words in this or any higher generation.
size_t max = 0; // 取可用空间多的代的剩余空间(只取1个Generation)
for (const Generation* gen = this; gen != NULL; gen = gen->next_gen()) {
size_t avail = gen->contiguous_available();
if (avail > max) {
max = avail;
}
}
return max;
}

contiguous_available

defNewGeneration.cpp

size_t DefNewGeneration::contiguous_available() const {
return eden()->free();
}

generation.cpp

size_t OneContigSpaceCardGeneration::contiguous_available() const {
return _the_space->free() + _virtual_space.uncommitted_size();
}