/* * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
bool ZRelocationSetSelectorGroup::is_disabled() { // Medium pages are disabled when their page size is zero return _page_type == ZPageTypeMedium && _page_size == 0;
}
bool ZRelocationSetSelectorGroup::is_selectable() { // Large pages are not selectable return _page_type != ZPageTypeLarge;
}
void ZRelocationSetSelectorGroup::semi_sort() { // Semi-sort live pages by number of live bytes in ascending order const size_t npartitions_shift = 11; const size_t npartitions = (size_t)1 << npartitions_shift; const size_t partition_size = _page_size >> npartitions_shift; const size_t partition_size_shift = exact_log2(partition_size);
// Partition slots/fingers int partitions[npartitions] = { /* zero initialize */ };
// Calculate partition slots
ZArrayIterator<ZPage*> iter1(&_live_pages); for (ZPage* page; iter1.next(&page);) { const size_t index = page->live_bytes() >> partition_size_shift;
partitions[index]++;
}
// Calculate partition fingers int finger = 0; for (size_t i = 0; i < npartitions; i++) { constint slots = partitions[i];
partitions[i] = finger;
finger += slots;
}
void ZRelocationSetSelectorGroup::select_inner() { // Calculate the number of pages to relocate by successively including pages in // a candidate relocation set and calculate the maximum space requirement for // their live objects. constint npages = _live_pages.length(); int selected_from = 0; int selected_to = 0;
size_t selected_live_bytes = 0;
size_t selected_forwarding_entries = 0;
size_t from_live_bytes = 0;
size_t from_forwarding_entries = 0;
semi_sort();
for (int from = 1; from <= npages; from++) { // Add page to the candidate relocation set
ZPage* const page = _live_pages.at(from - 1);
from_live_bytes += page->live_bytes();
from_forwarding_entries += ZForwarding::nentries(page);
// Calculate the maximum number of pages needed by the candidate relocation set. // By subtracting the object size limit from the pages size we get the maximum // number of pages that the relocation set is guaranteed to fit in, regardless // of in which order the objects are relocated. constint to = ceil((double)(from_live_bytes) / (double)(_page_size - _object_size_limit));
// Calculate the relative difference in reclaimable space compared to our // currently selected final relocation set. If this number is larger than the // acceptable fragmentation limit, then the current candidate relocation set // becomes our new final relocation set. constint diff_from = from - selected_from; constint diff_to = to - selected_to; constdouble diff_reclaimable = 100 - percent_of(diff_to, diff_from); if (diff_reclaimable > ZFragmentationLimit) {
selected_from = from;
selected_to = to;
selected_live_bytes = from_live_bytes;
selected_forwarding_entries = from_forwarding_entries;
}
void ZRelocationSetSelector::select() { // Select pages to relocate. The resulting relocation set will be // sorted such that medium pages comes first, followed by small // pages. Pages within each page group will be semi-sorted by live // bytes in ascending order. Relocating pages in this order allows // us to start reclaiming memory more quickly.
EventZRelocationSet event;
// Select pages from each group
_large.select();
_medium.select();
_small.select();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.