提交 3fddbba6 编写于 作者: A apetrusenko

6870843: G1: G1 GC memory leak

Summary: The fix addresses two memory leaks in G1 code: (1) _evac_failure_scan_stack - a resource object allocated on the C heap was not freed; (2) RSHashTable were linked into deleted list which was only cleared at full GC.
Reviewed-by: tonyp, iveresov
上级 c6ba230f
......@@ -3136,7 +3136,7 @@ void G1CollectedHeap::finalize_for_evac_failure() {
_evac_failure_scan_stack->length() == 0,
"Postcondition");
assert(!_drain_in_progress, "Postcondition");
// Don't have to delete, since the scan stack is a resource object.
delete _evac_failure_scan_stack;
_evac_failure_scan_stack = NULL;
}
......
......@@ -135,7 +135,6 @@ RSHashTable::RSHashTable(size_t capacity) :
_occupied_entries(0), _occupied_cards(0),
_entries(NEW_C_HEAP_ARRAY(SparsePRTEntry, capacity)),
_buckets(NEW_C_HEAP_ARRAY(int, capacity)),
_next_deleted(NULL), _deleted(false),
_free_list(NullEntry), _free_region(0)
{
clear();
......@@ -296,40 +295,6 @@ void RSHashTable::add_entry(SparsePRTEntry* e) {
assert(e2->num_valid_cards() > 0, "Postcondition.");
}
RSHashTable* RSHashTable::_head_deleted_list = NULL;
void RSHashTable::add_to_deleted_list(RSHashTable* rsht) {
assert(!rsht->deleted(), "Should delete only once.");
rsht->set_deleted(true);
RSHashTable* hd = _head_deleted_list;
while (true) {
rsht->_next_deleted = hd;
RSHashTable* res =
(RSHashTable*)
Atomic::cmpxchg_ptr(rsht, &_head_deleted_list, hd);
if (res == hd) return;
else hd = res;
}
}
RSHashTable* RSHashTable::get_from_deleted_list() {
RSHashTable* hd = _head_deleted_list;
while (hd != NULL) {
RSHashTable* next = hd->next_deleted();
RSHashTable* res =
(RSHashTable*)
Atomic::cmpxchg_ptr(next, &_head_deleted_list, hd);
if (res == hd) {
hd->set_next_deleted(NULL);
hd->set_deleted(false);
return hd;
} else {
hd = res;
}
}
return NULL;
}
CardIdx_t /* RSHashTable:: */ RSHashTableIter::find_first_card_in_list() {
CardIdx_t res;
while (_bl_ind != RSHashTable::NullEntry) {
......@@ -442,15 +407,6 @@ void SparsePRT::cleanup_all() {
sprt->cleanup();
sprt = get_from_expanded_list();
}
// Now delete all deleted RSHashTables.
RSHashTable* rsht = RSHashTable::get_from_deleted_list();
while (rsht != NULL) {
#if SPARSE_PRT_VERBOSE
gclog_or_tty->print_cr("About to delete RSHT " PTR_FORMAT ".", rsht);
#endif
delete rsht;
rsht = RSHashTable::get_from_deleted_list();
}
}
......@@ -511,8 +467,10 @@ void SparsePRT::clear() {
}
void SparsePRT::cleanup() {
// Make sure that the current and next tables agree. (Another mechanism
// takes care of deleting now-unused tables.)
// Make sure that the current and next tables agree.
if (_cur != _next) {
delete _cur;
}
_cur = _next;
set_expanded(false);
}
......@@ -535,7 +493,8 @@ void SparsePRT::expand() {
_next->add_entry(e);
}
}
if (last != _cur)
RSHashTable::add_to_deleted_list(last);
if (last != _cur) {
delete last;
}
add_to_expanded_list(this);
}
......@@ -102,13 +102,6 @@ class RSHashTable : public CHeapObj {
int _free_region;
int _free_list;
static RSHashTable* _head_deleted_list;
RSHashTable* _next_deleted;
RSHashTable* next_deleted() { return _next_deleted; }
void set_next_deleted(RSHashTable* rsht) { _next_deleted = rsht; }
bool _deleted;
void set_deleted(bool b) { _deleted = b; }
// Requires that the caller hold a lock preventing parallel modifying
// operations, and that the the table be less than completely full. If
// an entry for "region_ind" is already in the table, finds it and
......@@ -154,14 +147,10 @@ public:
size_t occupied_entries() const { return _occupied_entries; }
size_t occupied_cards() const { return _occupied_cards; }
size_t mem_size() const;
bool deleted() { return _deleted; }
SparsePRTEntry* entry(int i) const { return &_entries[i]; }
void print();
static void add_to_deleted_list(RSHashTable* rsht);
static RSHashTable* get_from_deleted_list();
};
// ValueObj because will be embedded in HRRS iterator.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册