1 /* 2 * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2018, 2020 SAP SE. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #ifndef SHARE_MEMORY_METASPACE_MSCHUNKMANAGER_HPP 27 #define SHARE_MEMORY_METASPACE_MSCHUNKMANAGER_HPP 28 29 #include "memory/allocation.hpp" 30 #include "memory/metaspace/msChunklevel.hpp" 31 #include "memory/metaspace/msCounter.hpp" 32 #include "memory/metaspace/msFreeChunkList.hpp" 33 #include "memory/metaspace/msMetachunk.hpp" 34 35 namespace metaspace { 36 37 class VirtualSpaceList; 38 struct ChunkManagerStats; 39 40 // ChunkManager has a somewhat central role. 41 42 // Arenas request chunks from it and, on death, return chunks back to it. 43 // It keeps freelists for chunks, one per chunk level, sorted by chunk 44 // commit state. 45 // To feed the freelists, it allocates root chunks from the associated 46 // VirtualSpace below it. 47 // 48 // ChunkManager directs splitting chunks, if a chunk request cannot be 49 // fulfilled directly. It also takes care of merging when chunks are 50 // returned to it, before they are added to the freelist. 51 // 52 // The freelists are double linked double headed; fully committed chunks 53 // are added to the front, others to the back. 54 // 55 // Level 56 // +--------------------+ +--------------------+ 57 // 0 +----| free root chunk |---| free root chunk |---... 58 // | +--------------------+ +--------------------+ 59 // | 60 // | +----------+ +----------+ 61 // 1 +----| |---| |---... 62 // | +----------+ +----------+ 63 // | 64 // . 65 // . 66 // . 67 // 68 // | +-+ +-+ 69 // 12 +----| |---| |---... 70 // +-+ +-+ 71 72 class ChunkManager : public CHeapObj<mtMetaspace> { 73 74 // A chunk manager is connected to a virtual space list which is used 75 // to allocate new root chunks when no free chunks are found. 76 VirtualSpaceList* const _vslist; 77 78 // Name 79 const char* const _name; 80 81 // Freelists 82 FreeChunkListVector _chunks; 83 84 // Returns true if this manager contains the given chunk. Slow (walks free lists) and 85 // only needed for verifications. 86 DEBUG_ONLY(bool contains_chunk(Metachunk* c) const;) 87 88 // Given a chunk, split it into a target chunk of a smaller size (target level) 89 // at least one, possible more splinter chunks. Splinter chunks are added to the 90 // freelist. 91 // The original chunk must be outside of the freelist and its state must be free. 92 // The resulting target chunk will be located at the same address as the original 93 // chunk, but it will of course be smaller (of a higher level). 94 // The committed areas within the original chunk carry over to the resulting 95 // chunks. 96 void split_chunk_and_add_splinters(Metachunk* c, chunklevel_t target_level); 97 98 // See get_chunk(s,s,s) 99 Metachunk* get_chunk_locked(size_t preferred_word_size, size_t min_word_size, size_t min_committed_words); 100 101 // Uncommit all chunks equal or below the given level. 102 void uncommit_free_chunks(chunklevel_t max_level); 103 104 // Return a single chunk to the freelist without doing any merging, and adjust accounting. 105 void return_chunk_simple_locked(Metachunk* c); 106 107 // See return_chunk(). 108 void return_chunk_locked(Metachunk* c); 109 110 public: 111 112 // Creates a chunk manager with a given name (which is for debug purposes only) 113 // and an associated space list which will be used to request new chunks from 114 // (see get_chunk()) 115 ChunkManager(const char* name, VirtualSpaceList* space_list); 116 117 // On success, returns a chunk of level of <preferred_level>, but at most <max_level>. 118 // The first first <min_committed_words> of the chunk are guaranteed to be committed. 119 // On error, will return NULL. 120 // 121 // This function may fail for two reasons: 122 // - Either we are unable to reserve space for a new chunk (if the underlying VirtualSpaceList 123 // is non-expandable but needs expanding - aka out of compressed class space). 124 // - Or, if the necessary space cannot be committed because we hit a commit limit. 125 // This may be either the GC threshold or MaxMetaspaceSize. 126 Metachunk* get_chunk(chunklevel_t preferred_level, chunklevel_t max_level, size_t min_committed_words); 127 128 // Convenience function - get a chunk of a given level, uncommitted. 129 Metachunk* get_chunk(chunklevel_t lvl) { return get_chunk(lvl, lvl, 0); } 130 131 // Return a single chunk to the ChunkManager and adjust accounting. May merge chunk 132 // with neighbors. 133 // Happens after a Classloader was unloaded and releases its metaspace chunks. 134 // !! Notes: 135 // 1) After this method returns, c may not be valid anymore. ** Do not access c after this function returns **. 136 // 2) This function will not remove c from its current chunk list. This has to be done by the caller prior to 137 // calling this method. 138 void return_chunk(Metachunk* c); 139 140 // Given a chunk c, which must be "in use" and must not be a root chunk, attempt to 141 // enlarge it in place by claiming its trailing buddy. 142 // 143 // This will only work if c is the leader of the buddy pair and the trailing buddy is free. 144 // 145 // If successful, the follower chunk will be removed from the freelists, the leader chunk c will 146 // double in size (level decreased by one). 147 // 148 // On success, true is returned, false otherwise. 149 bool attempt_enlarge_chunk(Metachunk* c); 150 151 // Attempt to reclaim free areas in metaspace wholesale: 152 // - first, attempt to purge nodes of the backing virtual space list: nodes which are completely 153 // unused get unmapped and deleted completely. 154 // - second, it will uncommit free chunks depending on commit granule size. 155 void purge(); 156 157 // Run verifications. slow=true: verify chunk-internal integrity too. 158 DEBUG_ONLY(void verify() const;) 159 DEBUG_ONLY(void verify_locked() const;) 160 161 // Returns the name of this chunk manager. 162 const char* name() const { return _name; } 163 164 // Returns total number of chunks 165 int total_num_chunks() const { return _chunks.num_chunks(); } 166 167 // Returns number of words in all free chunks (regardless of commit state). 168 size_t total_word_size() const { return _chunks.word_size(); } 169 170 // Returns number of committed words in all free chunks. 171 size_t total_committed_word_size() const { return _chunks.committed_word_size(); } 172 173 // Update statistics. 174 void add_to_statistics(ChunkManagerStats* out) const; 175 176 void print_on(outputStream* st) const; 177 void print_on_locked(outputStream* st) const; 178 179 // Convenience methods to return the global class-space chunkmanager 180 // and non-class chunkmanager, respectively. 181 static ChunkManager* chunkmanager_class(); 182 static ChunkManager* chunkmanager_nonclass(); 183 184 }; 185 186 } // namespace metaspace 187 188 #endif // SHARE_MEMORY_METASPACE_MSCHUNKMANAGER_HPP