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