/* * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2022 SAP SE. 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. *
*/
/* * This counter class counts memory allocation and deallocation, * records total memory allocation size and number of allocations. * The counters are updated atomically.
*/ class MemoryCounter { private: volatile size_t _count; volatile size_t _size;
#ifdef ASSERT // Peak size and count. Note: Peak count is the count at the point // peak size was reached, not the absolute highest peak count. volatile size_t _peak_count; volatile size_t _peak_size; void update_peak(size_t size, size_t cnt); #endif// ASSERT
/* * Malloc memory used by a particular subsystem. * It includes the memory acquired through os::malloc() * call and arena's backing memory.
*/ class MallocMemory { private:
MemoryCounter _malloc;
MemoryCounter _arena;
// A snapshot of malloc'd memory, includes malloc memory // usage by types and memory used by tracking itself. class MallocMemorySnapshot : public ResourceObj { friendclass MallocMemorySummary;
void copy_to(MallocMemorySnapshot* s) { // Need to make sure that mtChunks don't get deallocated while the // copy is going on, because their size is adjusted using this // buffer in make_adjustment().
ThreadCritical tc;
s->_all_mallocs = _all_mallocs; for (int index = 0; index < mt_number_of_types; index ++) {
s->_malloc[index] = _malloc[index];
}
}
// Make adjustment by subtracting chunks used by arenas // from total chunks to get total free chunk size void make_adjustment();
};
/* * This class is for collecting malloc statistics at summary level
*/ class MallocMemorySummary : AllStatic { private: // Reserve memory for placement of MallocMemorySnapshot object static size_t _snapshot[CALC_OBJ_SIZE_IN_TYPE(MallocMemorySnapshot, size_t)];
staticvoid check_limits_after_allocation(MEMFLAGS flag) { // We can only either have a total limit or category specific limits, // not both. if (_total_limit != 0) {
size_t s = as_snapshot()->total(); if (s > _total_limit) {
total_limit_reached(s, _total_limit);
}
} else {
size_t per_cat_limit = _limits_per_category[(int)flag]; if (per_cat_limit > 0) { const MallocMemory* mm = as_snapshot()->by_type(flag);
size_t s = mm->malloc_size() + mm->arena_size(); if (s > per_cat_limit) {
category_limit_reached(s, per_cat_limit, flag);
}
}
}
}
// Main class called from MemTracker to track malloc activities class MallocTracker : AllStatic { public: // Initialize malloc tracker for specific tracking level staticbool initialize(NMT_TrackingLevel level);
// The overhead that is incurred by switching on NMT (we need, per malloc allocation, // space for header and 16-bit footer) staticconst size_t overhead_per_malloc = sizeof(MallocHeader) + sizeof(uint16_t);
// Parameter name convention: // memblock : the beginning address for user data // malloc_base: the beginning address that includes malloc tracking header // // The relationship: // memblock = (char*)malloc_base + sizeof(nmt header) //
// Record malloc on specified memory block staticvoid* record_malloc(void* malloc_base, size_t size, MEMFLAGS flags, const NativeCallStack& stack);
// Given a block returned by os::malloc() or os::realloc(): // deaccount block from NMT, mark its header as dead and return pointer to header. staticvoid* record_free_block(void* memblock); // Given the free info from a block, de-account block from NMT. staticvoid deaccount(MallocHeader::FreeInfo free_info);
// Given a pointer, if it seems to point to the start of a valid malloced block, // print the block. Note that since there is very low risk of memory looking // accidentally like a valid malloc block header (canaries and all) this is not // totally failproof. Only use this during debugging or when you can afford // signals popping up, e.g. when writing an hs_err file. staticbool print_pointer_information(constvoid* p, outputStream* st);
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.