src/share/vm/memory/metaspace.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/memory/metaspace.cpp Sat May 16 14:36:37 2015
--- new/src/share/vm/memory/metaspace.cpp Sat May 16 14:36:36 2015
*** 613,624 ****
--- 613,623 ----
// are done from the current chunk. The list is used for deallocating
// chunks when the SpaceManager is freed.
Metachunk* _chunks_in_use[NumberOfInUseLists];
Metachunk* _current_chunk;
// Number of small chunks to allocate to a manager
// If class space manager, small chunks are unlimited
+ // Maximum number of small chunks to allocate to a SpaceManager
static uint const _small_chunk_limit;
// Sum of all space in allocated chunks
size_t _allocated_blocks_words;
*** 2010,2022 ****
--- 2009,2020 ----
}
size_t SpaceManager::calc_chunk_size(size_t word_size) {
// Decide between a small chunk and a medium chunk. Up to
! // _small_chunk_limit small chunks can be allocated but
// once a medium chunk has been allocated, no more small
// chunks will be allocated.
! // _small_chunk_limit small chunks can be allocated.
+ // After that a medium chunk is preferred.
size_t chunk_word_size;
if (chunks_in_use(MediumIndex) == NULL &&
sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) {
chunk_word_size = (size_t) small_chunk_size();
if (word_size + Metachunk::overhead() > small_chunk_size()) {
*** 2059,2068 ****
--- 2057,2076 ----
}
MemoryService::track_metaspace_memory_usage();
}
}
+ /*
+ * The policy is to allocate up to _small_chunk_limit small chunks
+ * after which only medium chunks are allocated. This is done to
+ * reduce fragmentation. In some cases, this can result in a lot
+ * of small chunks being allocated to the point where it's not
+ * possible to expand. If this happens, there may be no medium chunks
+ * available and OOME would be thrown. Instead of doing that,
+ * if the allocation request size fits in a small chunk, an attempt
+ * will be made to allocate a small chunk.
+ */
MetaWord* SpaceManager::grow_and_allocate(size_t word_size) {
assert(vs_list()->current_virtual_space() != NULL,
"Should have been set");
assert(current_chunk() == NULL ||
current_chunk()->allocate(word_size) == NULL,
*** 2080,2095 ****
--- 2088,2113 ----
" words " SIZE_FORMAT " words used " SIZE_FORMAT
" words left",
word_size, words_used, words_left);
}
- // Get another chunk out of the virtual space
size_t grow_chunks_by_words = calc_chunk_size(word_size);
Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words);
MetaWord* mem = NULL;
+ if (next == NULL &&
+ word_size + Metachunk::overhead() <= small_chunk_size() &&
+ grow_chunks_by_words == medium_chunk_size()) {
+ /*
+ * There are no medium chunks available but a small chunk is big enough.
+ * See if a small chunk is available.
+ */
+ next = get_new_chunk(word_size, small_chunk_size());
+ }
+
// If a chunk was available, add it to the in-use chunk list
// and do an allocation from it.
if (next != NULL) {
// Add to this manager's list of chunks in use.
add_chunk(next, false);
src/share/vm/memory/metaspace.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File