提交 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() { ...@@ -3136,7 +3136,7 @@ void G1CollectedHeap::finalize_for_evac_failure() {
_evac_failure_scan_stack->length() == 0, _evac_failure_scan_stack->length() == 0,
"Postcondition"); "Postcondition");
assert(!_drain_in_progress, "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; _evac_failure_scan_stack = NULL;
} }
......
...@@ -135,7 +135,6 @@ RSHashTable::RSHashTable(size_t capacity) : ...@@ -135,7 +135,6 @@ RSHashTable::RSHashTable(size_t capacity) :
_occupied_entries(0), _occupied_cards(0), _occupied_entries(0), _occupied_cards(0),
_entries(NEW_C_HEAP_ARRAY(SparsePRTEntry, capacity)), _entries(NEW_C_HEAP_ARRAY(SparsePRTEntry, capacity)),
_buckets(NEW_C_HEAP_ARRAY(int, capacity)), _buckets(NEW_C_HEAP_ARRAY(int, capacity)),
_next_deleted(NULL), _deleted(false),
_free_list(NullEntry), _free_region(0) _free_list(NullEntry), _free_region(0)
{ {
clear(); clear();
...@@ -296,40 +295,6 @@ void RSHashTable::add_entry(SparsePRTEntry* e) { ...@@ -296,40 +295,6 @@ void RSHashTable::add_entry(SparsePRTEntry* e) {
assert(e2->num_valid_cards() > 0, "Postcondition."); 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 /* RSHashTable:: */ RSHashTableIter::find_first_card_in_list() {
CardIdx_t res; CardIdx_t res;
while (_bl_ind != RSHashTable::NullEntry) { while (_bl_ind != RSHashTable::NullEntry) {
...@@ -442,15 +407,6 @@ void SparsePRT::cleanup_all() { ...@@ -442,15 +407,6 @@ void SparsePRT::cleanup_all() {
sprt->cleanup(); sprt->cleanup();
sprt = get_from_expanded_list(); 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() { ...@@ -511,8 +467,10 @@ void SparsePRT::clear() {
} }
void SparsePRT::cleanup() { void SparsePRT::cleanup() {
// Make sure that the current and next tables agree. (Another mechanism // Make sure that the current and next tables agree.
// takes care of deleting now-unused tables.) if (_cur != _next) {
delete _cur;
}
_cur = _next; _cur = _next;
set_expanded(false); set_expanded(false);
} }
...@@ -535,7 +493,8 @@ void SparsePRT::expand() { ...@@ -535,7 +493,8 @@ void SparsePRT::expand() {
_next->add_entry(e); _next->add_entry(e);
} }
} }
if (last != _cur) if (last != _cur) {
RSHashTable::add_to_deleted_list(last); delete last;
}
add_to_expanded_list(this); add_to_expanded_list(this);
} }
...@@ -102,13 +102,6 @@ class RSHashTable : public CHeapObj { ...@@ -102,13 +102,6 @@ class RSHashTable : public CHeapObj {
int _free_region; int _free_region;
int _free_list; 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 // Requires that the caller hold a lock preventing parallel modifying
// operations, and that the the table be less than completely full. If // 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 // an entry for "region_ind" is already in the table, finds it and
...@@ -154,14 +147,10 @@ public: ...@@ -154,14 +147,10 @@ public:
size_t occupied_entries() const { return _occupied_entries; } size_t occupied_entries() const { return _occupied_entries; }
size_t occupied_cards() const { return _occupied_cards; } size_t occupied_cards() const { return _occupied_cards; }
size_t mem_size() const; size_t mem_size() const;
bool deleted() { return _deleted; }
SparsePRTEntry* entry(int i) const { return &_entries[i]; } SparsePRTEntry* entry(int i) const { return &_entries[i]; }
void print(); void print();
static void add_to_deleted_list(RSHashTable* rsht);
static RSHashTable* get_from_deleted_list();
}; };
// ValueObj because will be embedded in HRRS iterator. // 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.
先完成此消息的编辑!
想要评论请 注册