#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
// 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();
};
/* *Thisclassisforcollectingmallocstatisticsatsummarylevel
*/ 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.