src/hotspot/share/memory/metaspace/chunkManager.cpp
branchstuefe-new-metaspace-branch
changeset 58717 5e9e519e5dc9
parent 58716 960e372a6065
equal deleted inserted replaced
58716:960e372a6065 58717:5e9e519e5dc9
   161   log_debug(metaspace)("ChunkManager %s: get chunk: max " CHKLVL_FORMAT " (" SIZE_FORMAT "),"
   161   log_debug(metaspace)("ChunkManager %s: get chunk: max " CHKLVL_FORMAT " (" SIZE_FORMAT "),"
   162                        "preferred " CHKLVL_FORMAT " (" SIZE_FORMAT ").",
   162                        "preferred " CHKLVL_FORMAT " (" SIZE_FORMAT ").",
   163                        _name, max_level, chklvl::word_size_for_level(max_level),
   163                        _name, max_level, chklvl::word_size_for_level(max_level),
   164                        pref_level, chklvl::word_size_for_level(pref_level));
   164                        pref_level, chklvl::word_size_for_level(pref_level));
   165 
   165 
       
   166   // When handing a new chunk to the caller, we must balance the need to not let free space go to waste
       
   167   // with the need to keep fragmentation low.
       
   168   // Every request comes with a preferred chunk size and the minimum chunk size, which is the bare minimum
       
   169   // needed to house the metadata allocation which triggered this chunk allocation.
       
   170   //
       
   171   // Ideally, we have a free chunk of the preferred size just laying around and hand that one out.
       
   172   // Realistically, we are often faced with the choice of either taking a larger chunk and split it
       
   173   // or taking a smaller chunk than the preferred size. Both has pros and cons: splitting a larger chunk
       
   174   // reduces the number of large chunks available for large allocations, and, increases fragmentation.
       
   175   // Using a smaller chunk may also increase fragmentation (beside being inefficient at some point) if
       
   176   // e.g. a normal class loader - which lives normally off 64K chunks - eats from the bowl of small chunk
       
   177   // loaders, which prefer 4K or 1K chunks.
       
   178 
   166   // 1) Attempt to find a free chunk of exactly the pref_level level
   179   // 1) Attempt to find a free chunk of exactly the pref_level level
   167   c = remove_first_chunk_at_level(pref_level);
   180   c = remove_first_chunk_at_level(pref_level);
   168 
   181 
   169   // 2) Failing that, we are also willing to accept a chunk half that size, but nothing less for now...
   182   // 2) Failing that, we are also willing to accept a smaller chunk, but only up to a limit
       
   183   //    (for now, half the preferred size)...
   170   if (c == NULL && pref_level < max_level) {
   184   if (c == NULL && pref_level < max_level) {
   171     c = remove_first_chunk_at_level(pref_level + 1);
   185     c = remove_first_chunk_at_level(pref_level + 1);
   172   }
   186   }
   173 
   187 
   174   // 3) Failing that, attempt to find a free chunk of larger size and split it to get the ideal size...
   188   // 3) Failing that, attempt to find a free chunk of larger size and split it to the preferred size...
   175   if (c == NULL) {
   189   if (c == NULL) {
   176     for (chklvl_t lvl = pref_level - 1; lvl >= chklvl::ROOT_CHUNK_LEVEL; lvl --) {
   190     for (chklvl_t lvl = pref_level - 1; lvl >= chklvl::ROOT_CHUNK_LEVEL; lvl --) {
   177       c = remove_first_chunk_at_level(lvl);
   191       c = remove_first_chunk_at_level(lvl);
   178       if (c != NULL) {
   192       if (c != NULL) {
   179         // Split chunk; add splinters to freelist
   193         // Split chunk; add splinters to freelist
   181         break;
   195         break;
   182       }
   196       }
   183     }
   197     }
   184   }
   198   }
   185 
   199 
   186   // 4) Failing that, before we start allocating a new root chunk, lets really scrape the barrel. Any
   200   // 4) Failing that, before we give up and get a new root chunk, lets really scrape the barrel. Any
   187   //    smaller chunk is acceptable provided it fits the minimal size....
   201   //    smaller chunk is acceptable now...
   188   if (c == NULL) {
   202   if (c == NULL) {
   189     for (chklvl_t lvl = pref_level + 1; lvl <= max_level; lvl ++) {
   203     for (chklvl_t lvl = pref_level + 2; lvl <= max_level; lvl ++) {
   190       c = remove_first_chunk_at_level(lvl);
   204       c = remove_first_chunk_at_level(lvl);
   191       if (c != NULL) {
   205       if (c != NULL) {
   192         break;
   206         break;
   193       }
   207       }
   194     }
   208     }
   195   }
   209   }
   196 
   210 
   197   // 4) Failing that, attempt to allocate a new root chunk from the connected virtual space.
   211   // 5) Failing all that, allocate a new root chunk from the connected virtual space.
   198   if (c == NULL) {
   212   if (c == NULL) {
   199 
   213 
   200     // Tracing
   214     // Tracing
   201     log_debug(metaspace)("ChunkManager %s: need new root chunk.", _name);
   215     log_debug(metaspace)("ChunkManager %s: need new root chunk.", _name);
   202 
   216 
   208       return NULL;
   222       return NULL;
   209     }
   223     }
   210 
   224 
   211     assert(c->level() == chklvl::LOWEST_CHUNK_LEVEL, "Not a root chunk?");
   225     assert(c->level() == chklvl::LOWEST_CHUNK_LEVEL, "Not a root chunk?");
   212 
   226 
   213     // Split this root chunk to the desired chunk size.
   227     // Split this root chunk to the desired chunk size. Splinters are added to freelist.
   214     if (pref_level > c->level()) {
   228     if (pref_level > c->level()) {
   215       c = split_chunk_and_add_splinters(c, pref_level);
   229       c = split_chunk_and_add_splinters(c, pref_level);
   216     }
   230     }
   217   }
   231   }
   218 
   232