Skip to content

Commit 02adaa5

Browse files
committed
8255885: Metaspace: freelist commit counter is not updated when purging
Reviewed-by: coleenp, iklam
1 parent fa240f2 commit 02adaa5

File tree

6 files changed

+49
-30
lines changed

6 files changed

+49
-30
lines changed

src/hotspot/share/memory/metaspace/chunkManager.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,12 +382,23 @@ ChunkManager* ChunkManager::chunkmanager_nonclass() {
382382
return MetaspaceContext::context_nonclass() == NULL ? NULL : MetaspaceContext::context_nonclass()->cm();
383383
}
384384

385+
// Calculates the total number of committed words over all chunks. Walks chunks.
386+
size_t ChunkManager::calc_committed_word_size() const {
387+
MutexLocker fcl(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
388+
return calc_committed_word_size_locked();
389+
}
390+
391+
size_t ChunkManager::calc_committed_word_size_locked() const {
392+
assert_lock_strong(MetaspaceExpand_lock);
393+
return _chunks.calc_committed_word_size();
394+
}
395+
385396
// Update statistics.
386397
void ChunkManager::add_to_statistics(ChunkManagerStats* out) const {
387398
MutexLocker fcl(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
388399
for (chunklevel_t l = chunklevel::ROOT_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {
389400
out->_num_chunks[l] += _chunks.num_chunks_at_level(l);
390-
out->_committed_word_size[l] += _chunks.committed_word_size_at_level(l);
401+
out->_committed_word_size[l] += _chunks.calc_committed_word_size_at_level(l);
391402
}
392403
DEBUG_ONLY(out->verify();)
393404
}
@@ -418,8 +429,8 @@ void ChunkManager::print_on(outputStream* st) const {
418429

419430
void ChunkManager::print_on_locked(outputStream* st) const {
420431
assert_lock_strong(MetaspaceExpand_lock);
421-
st->print_cr("cm %s: %d chunks, total word size: " SIZE_FORMAT ", committed word size: " SIZE_FORMAT, _name,
422-
total_num_chunks(), total_word_size(), _chunks.committed_word_size());
432+
st->print_cr("cm %s: %d chunks, total word size: " SIZE_FORMAT ".", _name,
433+
total_num_chunks(), total_word_size());
423434
_chunks.print_on(st);
424435
}
425436

src/hotspot/share/memory/metaspace/chunkManager.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ class ChunkManager : public CHeapObj<mtMetaspace> {
107107
// See return_chunk().
108108
void return_chunk_locked(Metachunk* c);
109109

110+
// Calculates the total number of committed words over all chunks. Walks chunks.
111+
size_t calc_committed_word_size_locked() const;
112+
110113
public:
111114

112115
// Creates a chunk manager with a given name (which is for debug purposes only)
@@ -167,8 +170,8 @@ class ChunkManager : public CHeapObj<mtMetaspace> {
167170
// Returns number of words in all free chunks (regardless of commit state).
168171
size_t total_word_size() const { return _chunks.word_size(); }
169172

170-
// Returns number of committed words in all free chunks.
171-
size_t total_committed_word_size() const { return _chunks.committed_word_size(); }
173+
// Calculates the total number of committed words over all chunks. Walks chunks.
174+
size_t calc_committed_word_size() const;
172175

173176
// Update statistics.
174177
void add_to_statistics(ChunkManagerStats* out) const;

src/hotspot/share/memory/metaspace/freeChunkList.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@
3131

3232
namespace metaspace {
3333

34+
// Calculates total number of committed words over all chunks (walks chunks).
35+
size_t FreeChunkList::calc_committed_word_size() const {
36+
size_t s = 0;
37+
for (const Metachunk* c = _first; c != NULL; c = c->next()) {
38+
s += c->committed_words();
39+
}
40+
return s;
41+
}
42+
3443
void FreeChunkList::print_on(outputStream* st) const {
3544
if (_num_chunks.get() > 0) {
3645
for (const Metachunk* c = _first; c != NULL; c = c->next()) {
@@ -60,7 +69,6 @@ void FreeChunkList::verify() const {
6069
assert(_last == NULL, "Sanity");
6170
} else {
6271
assert(_last != NULL, "Sanity");
63-
size_t committed = 0;
6472
int num = 0;
6573
bool uncommitted = (_first->committed_words() == 0);
6674
for (Metachunk* c = _first; c != NULL; c = c->next()) {
@@ -71,11 +79,9 @@ void FreeChunkList::verify() const {
7179
assert(c->prev() == NULL || c->prev()->next() == c, "back link broken");
7280
assert(c != c->prev() && c != c->next(), "circle");
7381
c->verify();
74-
committed += c->committed_words();
7582
num++;
7683
}
7784
_num_chunks.check(num);
78-
_committed_word_size.check(committed);
7985
}
8086
}
8187

@@ -90,15 +96,19 @@ size_t FreeChunkListVector::word_size() const {
9096
return sum;
9197
}
9298

93-
// Returns total committed size in all lists
94-
size_t FreeChunkListVector::committed_word_size() const {
99+
// Calculates total number of committed words over all chunks (walks chunks).
100+
size_t FreeChunkListVector::calc_committed_word_size() const {
95101
size_t sum = 0;
96102
for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {
97-
sum += list_for_level(l)->committed_word_size();
103+
sum += calc_committed_word_size_at_level(l);
98104
}
99105
return sum;
100106
}
101107

108+
size_t FreeChunkListVector::calc_committed_word_size_at_level(chunklevel_t lvl) const {
109+
return list_for_level(lvl)->calc_committed_word_size();
110+
}
111+
102112
// Returns total committed size in all lists
103113
int FreeChunkListVector::num_chunks() const {
104114
int n = 0;
@@ -146,8 +156,8 @@ void FreeChunkListVector::print_on(outputStream* st) const {
146156
list_for_level(l)->print_on(st);
147157
st->cr();
148158
}
149-
st->print_cr("total chunks: %d, total word size: " SIZE_FORMAT ", committed word size: " SIZE_FORMAT ".",
150-
num_chunks(), word_size(), committed_word_size());
159+
st->print_cr("total chunks: %d, total word size: " SIZE_FORMAT ".",
160+
num_chunks(), word_size());
151161
}
152162

153163
#ifdef ASSERT

src/hotspot/share/memory/metaspace/freeChunkList.hpp

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ class FreeChunkList {
7070
Metachunk* _last;
7171

7272
IntCounter _num_chunks;
73-
SizeCounter _committed_word_size;
7473

7574
void add_front(Metachunk* c) {
7675
if (_first == NULL) {
@@ -129,7 +128,6 @@ class FreeChunkList {
129128
}
130129
c->set_next(NULL);
131130
c->set_prev(NULL);
132-
_committed_word_size.decrement_by(c->committed_words());
133131
_num_chunks.decrement();
134132
return c;
135133
}
@@ -144,7 +142,6 @@ class FreeChunkList {
144142
} else {
145143
add_front(c);
146144
}
147-
_committed_word_size.increment_by(c->committed_words());
148145
_num_chunks.increment();
149146
}
150147

@@ -186,8 +183,8 @@ class FreeChunkList {
186183
// Returns number of chunks
187184
int num_chunks() const { return _num_chunks.get(); }
188185

189-
// Returns total committed word size
190-
size_t committed_word_size() const { return _committed_word_size.get(); }
186+
// Calculates total number of committed words over all chunks (walks chunks).
187+
size_t calc_committed_word_size() const;
191188

192189
void print_on(outputStream* st) const;
193190

@@ -226,11 +223,6 @@ class FreeChunkListVector {
226223
return list_for_level(lvl)->num_chunks();
227224
}
228225

229-
// Returns number of chunks for a given level.
230-
size_t committed_word_size_at_level(chunklevel_t lvl) const {
231-
return list_for_level(lvl)->committed_word_size();
232-
}
233-
234226
// Returns reference to first chunk at this level, or NULL if sublist is empty.
235227
Metachunk* first_at_level(chunklevel_t lvl) const {
236228
return list_for_level(lvl)->first();
@@ -247,11 +239,14 @@ class FreeChunkListVector {
247239
// Return NULL if no such chunk was found.
248240
Metachunk* search_chunk_descending(chunklevel_t level, size_t min_committed_words);
249241

250-
// Returns total size in all lists (regardless of commit state of underlying memory)
242+
// Returns total size in all lists (including uncommitted areas)
251243
size_t word_size() const;
252244

253-
// Returns total committed size in all lists
254-
size_t committed_word_size() const;
245+
// Calculates total number of committed words over all chunks (walks chunks).
246+
size_t calc_committed_word_size_at_level(chunklevel_t lvl) const;
247+
248+
// Calculates total number of committed words over all chunks (walks chunks).
249+
size_t calc_committed_word_size() const;
255250

256251
// Returns number of chunks in all lists
257252
int num_chunks() const;

test/hotspot/gtest/metaspace/test_metachunklist.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ TEST_VM(metaspace, freechunklist) {
112112

113113
EXPECT_EQ(lst.num_chunks(), (int)cnt.count());
114114
EXPECT_EQ(lst.word_size(), cnt.total_size());
115-
EXPECT_EQ(lst.committed_word_size(), committed_cnt.total_size());
115+
EXPECT_EQ(lst.calc_committed_word_size(), committed_cnt.total_size());
116116
}
117117

118118
// Drain each list separately, front to back. While draining observe the order
@@ -137,7 +137,7 @@ TEST_VM(metaspace, freechunklist) {
137137

138138
EXPECT_EQ(lst.num_chunks(), (int)cnt.count());
139139
EXPECT_EQ(lst.word_size(), cnt.total_size());
140-
EXPECT_EQ(lst.committed_word_size(), committed_cnt.total_size());
140+
EXPECT_EQ(lst.calc_committed_word_size(), committed_cnt.total_size());
141141

142142
context.return_chunk(c);
143143

test/hotspot/gtest/metaspace/test_metaspacearena.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ static void test_recover_from_commit_limit_hit() {
504504
EXPECT_LE(allocated_from_3, Settings::commit_granule_words() * 2);
505505

506506
// We expect the freelist to be empty of committed space...
507-
EXPECT_0(context.cm().total_committed_word_size());
507+
EXPECT_0(context.cm().calc_committed_word_size());
508508

509509
//msthelper.cm().print_on(tty);
510510

@@ -515,7 +515,7 @@ static void test_recover_from_commit_limit_hit() {
515515

516516
// Should have populated the freelist with committed space
517517
// We expect the freelist to be empty of committed space...
518-
EXPECT_GT(context.cm().total_committed_word_size(), (size_t)0);
518+
EXPECT_GT(context.cm().calc_committed_word_size(), (size_t)0);
519519

520520
// Repeat allocation from helper3, should now work.
521521
helper3.allocate_from_arena_with_tests_expect_success(1);

0 commit comments

Comments
 (0)