zgu@3900: /* katleman@4376: * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. zgu@3900: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. zgu@3900: * zgu@3900: * This code is free software; you can redistribute it and/or modify it zgu@3900: * under the terms of the GNU General Public License version 2 only, as zgu@3900: * published by the Free Software Foundation. zgu@3900: * zgu@3900: * This code is distributed in the hope that it will be useful, but WITHOUT zgu@3900: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or zgu@3900: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License zgu@3900: * version 2 for more details (a copy is included in the LICENSE file that zgu@3900: * accompanied this code). zgu@3900: * zgu@3900: * You should have received a copy of the GNU General Public License version zgu@3900: * 2 along with this work; if not, write to the Free Software Foundation, zgu@3900: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. zgu@3900: * zgu@3900: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA zgu@3900: * or visit www.oracle.com if you need additional information or have any zgu@3900: * questions. zgu@3900: * zgu@3900: */ zgu@3900: zgu@3900: #ifndef SHARE_VM_SERVICES_MEM_REPORTER_HPP zgu@3900: #define SHARE_VM_SERVICES_MEM_REPORTER_HPP zgu@3900: zgu@3900: #include "runtime/mutexLocker.hpp" zgu@3900: #include "services/memBaseline.hpp" zgu@3900: #include "services/memTracker.hpp" zgu@3900: #include "utilities/ostream.hpp" zgu@3900: jprovino@4165: #if INCLUDE_NMT jprovino@4165: zgu@3900: /* zgu@3900: * MemBaselineReporter reports data to this outputer class, zgu@3900: * ReportOutputer is responsible for format, store and redirect zgu@3900: * the data to the final destination. zgu@3900: */ zgu@3900: class BaselineOutputer : public StackObj { zgu@3900: public: zgu@3900: // start to report memory usage in specified scale. zgu@3900: // if report_diff = true, the reporter reports baseline comparison zgu@3900: // information. zgu@3900: zgu@3900: virtual void start(size_t scale, bool report_diff = false) = 0; zgu@3900: // Done reporting zgu@3900: virtual void done() = 0; zgu@3900: zgu@3900: /* report baseline summary information */ zgu@3900: virtual void total_usage(size_t total_reserved, zgu@3900: size_t total_committed) = 0; zgu@3900: virtual void num_of_classes(size_t classes) = 0; zgu@3900: virtual void num_of_threads(size_t threads) = 0; zgu@3900: zgu@3900: virtual void thread_info(size_t stack_reserved_amt, size_t stack_committed_amt) = 0; zgu@3900: zgu@3900: /* report baseline summary comparison */ zgu@3900: virtual void diff_total_usage(size_t total_reserved, zgu@3900: size_t total_committed, zgu@3900: int reserved_diff, zgu@3900: int committed_diff) = 0; zgu@3900: virtual void diff_num_of_classes(size_t classes, int diff) = 0; zgu@3900: virtual void diff_num_of_threads(size_t threads, int diff) = 0; zgu@3900: zgu@3900: virtual void diff_thread_info(size_t stack_reserved, size_t stack_committed, zgu@3900: int stack_reserved_diff, int stack_committed_diff) = 0; zgu@3900: zgu@3900: zgu@3900: /* zgu@3900: * memory summary by memory types. zgu@3900: * for each memory type, following summaries are reported: zgu@3900: * - reserved amount, committed amount zgu@3900: * - malloc'd amount, malloc count zgu@3900: * - arena amount, arena count zgu@3900: */ zgu@3900: zgu@3900: // start reporting memory summary by memory type zgu@3900: virtual void start_category_summary() = 0; zgu@3900: zgu@3900: virtual void category_summary(MEMFLAGS type, size_t reserved_amt, zgu@3900: size_t committed_amt, zgu@3900: size_t malloc_amt, size_t malloc_count, zgu@3900: size_t arena_amt, size_t arena_count) = 0; zgu@3900: zgu@3900: virtual void diff_category_summary(MEMFLAGS type, size_t cur_reserved_amt, zgu@3900: size_t cur_committed_amt, zgu@3900: size_t cur_malloc_amt, size_t cur_malloc_count, zgu@3900: size_t cur_arena_amt, size_t cur_arena_count, zgu@3900: int reserved_diff, int committed_diff, int malloc_diff, zgu@3900: int malloc_count_diff, int arena_diff, zgu@3900: int arena_count_diff) = 0; zgu@3900: zgu@3900: virtual void done_category_summary() = 0; zgu@3900: zgu@4193: virtual void start_virtual_memory_map() = 0; zgu@4193: virtual void reserved_memory_region(MEMFLAGS type, address base, address end, size_t size, address pc) = 0; zgu@4193: virtual void committed_memory_region(address base, address end, size_t size, address pc) = 0; zgu@4193: virtual void done_virtual_memory_map() = 0; zgu@4193: zgu@3900: /* zgu@3900: * Report callsite information zgu@3900: */ zgu@3900: virtual void start_callsite() = 0; zgu@3900: virtual void malloc_callsite(address pc, size_t malloc_amt, size_t malloc_count) = 0; zgu@3900: virtual void virtual_memory_callsite(address pc, size_t reserved_amt, size_t committed_amt) = 0; zgu@3900: zgu@3900: virtual void diff_malloc_callsite(address pc, size_t cur_malloc_amt, size_t cur_malloc_count, zgu@3900: int malloc_diff, int malloc_count_diff) = 0; zgu@3900: virtual void diff_virtual_memory_callsite(address pc, size_t cur_reserved_amt, size_t cur_committed_amt, zgu@3900: int reserved_diff, int committed_diff) = 0; zgu@3900: zgu@3900: virtual void done_callsite() = 0; zgu@3900: zgu@3900: // return current scale in "KB", "MB" or "GB" zgu@3900: static const char* memory_unit(size_t scale); zgu@3900: }; zgu@3900: zgu@3900: /* zgu@3900: * This class reports processed data from a baseline or zgu@3900: * the changes between the two baseline. zgu@3900: */ zgu@3900: class BaselineReporter : public StackObj { zgu@3900: private: zgu@3900: BaselineOutputer& _outputer; zgu@3900: size_t _scale; zgu@3900: zgu@3900: public: zgu@3900: // construct a reporter that reports memory usage zgu@3900: // in specified scale zgu@3900: BaselineReporter(BaselineOutputer& outputer, size_t scale = K): zgu@3900: _outputer(outputer) { zgu@3900: _scale = scale; zgu@3900: } zgu@3900: virtual void report_baseline(const MemBaseline& baseline, bool summary_only = false); zgu@3900: virtual void diff_baselines(const MemBaseline& cur, const MemBaseline& prev, zgu@3900: bool summary_only = false); zgu@3900: zgu@3900: void set_scale(size_t scale); zgu@3900: size_t scale() const { return _scale; } zgu@3900: zgu@3900: private: zgu@3900: void report_summaries(const MemBaseline& baseline); zgu@4193: void report_virtual_memory_map(const MemBaseline& baseline); zgu@3900: void report_callsites(const MemBaseline& baseline); zgu@3900: zgu@3900: void diff_summaries(const MemBaseline& cur, const MemBaseline& prev); zgu@3900: void diff_callsites(const MemBaseline& cur, const MemBaseline& prev); zgu@3900: zgu@3900: // calculate memory size in current memory scale zgu@3900: size_t amount_in_current_scale(size_t amt) const; zgu@3900: // diff two unsigned values in current memory scale zgu@3900: int diff_in_current_scale(size_t value1, size_t value2) const; zgu@3900: // diff two unsigned value zgu@3900: int diff(size_t value1, size_t value2) const; zgu@3900: }; zgu@3900: zgu@3900: /* zgu@3900: * tty output implementation. Native memory tracking zgu@3900: * DCmd uses this outputer. zgu@3900: */ zgu@3900: class BaselineTTYOutputer : public BaselineOutputer { zgu@3900: private: zgu@3900: size_t _scale; zgu@3900: zgu@3900: size_t _num_of_classes; zgu@3900: size_t _num_of_threads; zgu@3900: size_t _thread_stack_reserved; zgu@3900: size_t _thread_stack_committed; zgu@3900: zgu@3900: int _num_of_classes_diff; zgu@3900: int _num_of_threads_diff; zgu@3900: int _thread_stack_reserved_diff; zgu@3900: int _thread_stack_committed_diff; zgu@3900: zgu@3900: outputStream* _output; zgu@3900: zgu@3900: public: zgu@3900: BaselineTTYOutputer(outputStream* st) { zgu@3900: _scale = K; zgu@3900: _num_of_classes = 0; zgu@3900: _num_of_threads = 0; zgu@3900: _thread_stack_reserved = 0; zgu@3900: _thread_stack_committed = 0; zgu@3900: _num_of_classes_diff = 0; zgu@3900: _num_of_threads_diff = 0; zgu@3900: _thread_stack_reserved_diff = 0; zgu@3900: _thread_stack_committed_diff = 0; zgu@3900: _output = st; zgu@3900: } zgu@3900: zgu@3900: // begin reporting memory usage in specified scale zgu@3900: void start(size_t scale, bool report_diff = false); zgu@3900: // done reporting zgu@3900: void done(); zgu@3900: zgu@3900: // total memory usage zgu@3900: void total_usage(size_t total_reserved, zgu@3900: size_t total_committed); zgu@3900: // report total loaded classes zgu@3900: void num_of_classes(size_t classes) { zgu@3900: _num_of_classes = classes; zgu@3900: } zgu@3900: zgu@3900: void num_of_threads(size_t threads) { zgu@3900: _num_of_threads = threads; zgu@3900: } zgu@3900: zgu@3900: void thread_info(size_t stack_reserved_amt, size_t stack_committed_amt) { zgu@3900: _thread_stack_reserved = stack_reserved_amt; zgu@3900: _thread_stack_committed = stack_committed_amt; zgu@3900: } zgu@3900: zgu@3900: void diff_total_usage(size_t total_reserved, zgu@3900: size_t total_committed, zgu@3900: int reserved_diff, zgu@3900: int committed_diff); zgu@3900: zgu@3900: void diff_num_of_classes(size_t classes, int diff) { zgu@3900: _num_of_classes = classes; zgu@3900: _num_of_classes_diff = diff; zgu@3900: } zgu@3900: zgu@3900: void diff_num_of_threads(size_t threads, int diff) { zgu@3900: _num_of_threads = threads; zgu@3900: _num_of_threads_diff = diff; zgu@3900: } zgu@3900: zgu@3900: void diff_thread_info(size_t stack_reserved_amt, size_t stack_committed_amt, zgu@3900: int stack_reserved_diff, int stack_committed_diff) { zgu@3900: _thread_stack_reserved = stack_reserved_amt; zgu@3900: _thread_stack_committed = stack_committed_amt; zgu@3900: _thread_stack_reserved_diff = stack_reserved_diff; zgu@3900: _thread_stack_committed_diff = stack_committed_diff; zgu@3900: } zgu@3900: zgu@3900: /* zgu@3900: * Report memory summary categoriuzed by memory types. zgu@3900: * For each memory type, following summaries are reported: zgu@3900: * - reserved amount, committed amount zgu@3900: * - malloc-ed amount, malloc count zgu@3900: * - arena amount, arena count zgu@3900: */ zgu@3900: // start reporting memory summary by memory type zgu@3900: void start_category_summary(); zgu@3900: void category_summary(MEMFLAGS type, size_t reserved_amt, size_t committed_amt, zgu@3900: size_t malloc_amt, size_t malloc_count, zgu@3900: size_t arena_amt, size_t arena_count); zgu@3900: zgu@3900: void diff_category_summary(MEMFLAGS type, size_t cur_reserved_amt, zgu@3900: size_t cur_committed_amt, zgu@3900: size_t cur_malloc_amt, size_t cur_malloc_count, zgu@3900: size_t cur_arena_amt, size_t cur_arena_count, zgu@3900: int reserved_diff, int committed_diff, int malloc_diff, zgu@3900: int malloc_count_diff, int arena_diff, zgu@3900: int arena_count_diff); zgu@3900: zgu@3900: void done_category_summary(); zgu@3900: zgu@4193: // virtual memory map zgu@4193: void start_virtual_memory_map(); zgu@4193: void reserved_memory_region(MEMFLAGS type, address base, address end, size_t size, address pc); zgu@4193: void committed_memory_region(address base, address end, size_t size, address pc); zgu@4193: void done_virtual_memory_map(); zgu@4193: zgu@4193: zgu@3900: /* zgu@3900: * Report callsite information zgu@3900: */ zgu@3900: void start_callsite(); zgu@3900: void malloc_callsite(address pc, size_t malloc_amt, size_t malloc_count); zgu@3900: void virtual_memory_callsite(address pc, size_t reserved_amt, size_t committed_amt); zgu@3900: zgu@3900: void diff_malloc_callsite(address pc, size_t cur_malloc_amt, size_t cur_malloc_count, zgu@3900: int malloc_diff, int malloc_count_diff); zgu@3900: void diff_virtual_memory_callsite(address pc, size_t cur_reserved_amt, size_t cur_committed_amt, zgu@3900: int reserved_diff, int committed_diff); zgu@3900: zgu@3900: void done_callsite(); zgu@3900: }; zgu@3900: zgu@3900: jprovino@4165: #endif // INCLUDE_NMT jprovino@4165: zgu@3900: #endif // SHARE_VM_SERVICES_MEM_REPORTER_HPP