1 /*
2 * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
2727 out->print_cr(" Committed size : " SIZE_FORMAT_W(7) " KB", CodeCache::capacity() / K);
2728 out->print_cr(" Unallocated capacity : " SIZE_FORMAT_W(7) " KB", CodeCache::unallocated_capacity() / K);
2729 out->cr();
2730
2731 out->cr();
2732 out->print_cr("CodeCache cleaning overview");
2733 out->print_cr("--------------------------------------------------------");
2734 out->cr();
2735 NMethodSweeper::print(out);
2736 out->print_cr("--------------------------------------------------------");
2737 out->cr();
2738 }
2739
2740 // Note: tty_lock must not be held upon entry to this function.
2741 // Print functions called from herein do "micro-locking" on tty_lock.
2742 // That's a tradeoff which keeps together important blocks of output.
2743 // At the same time, continuous tty_lock hold time is kept in check,
2744 // preventing concurrently printing threads from stalling a long time.
2745 void CompileBroker::print_heapinfo(outputStream* out, const char* function, size_t granularity) {
2746 TimeStamp ts_total;
2747 TimeStamp ts;
2748
2749 bool allFun = !strcmp(function, "all");
2750 bool aggregate = !strcmp(function, "aggregate") || !strcmp(function, "analyze") || allFun;
2751 bool usedSpace = !strcmp(function, "UsedSpace") || allFun;
2752 bool freeSpace = !strcmp(function, "FreeSpace") || allFun;
2753 bool methodCount = !strcmp(function, "MethodCount") || allFun;
2754 bool methodSpace = !strcmp(function, "MethodSpace") || allFun;
2755 bool methodAge = !strcmp(function, "MethodAge") || allFun;
2756 bool methodNames = !strcmp(function, "MethodNames") || allFun;
2757 bool discard = !strcmp(function, "discard") || allFun;
2758
2759 if (out == NULL) {
2760 out = tty;
2761 }
2762
2763 if (!(aggregate || usedSpace || freeSpace || methodCount || methodSpace || methodAge || methodNames || discard)) {
2764 out->print_cr("\n__ CodeHeapStateAnalytics: Function %s is not supported", function);
2765 out->cr();
2766 return;
2767 }
2768
2769 ts_total.update(); // record starting point
2770
2771 if (aggregate) {
2772 print_info(out);
2773 }
2774
2775 // We hold the CodeHeapStateAnalytics_lock all the time, from here until we leave this function.
2776 // That helps us getting a consistent view on the CodeHeap, at least for the "all" function.
2777 // When we request individual parts of the analysis via the jcmd interface, it is possible
2778 // that in between another thread (another jcmd user or the vm running into CodeCache OOM)
2779 // updated the aggregated data. That's a tolerable tradeoff because we can't hold a lock
2780 // across user interaction.
2781 ts.update(); // record starting point
2782 MutexLockerEx mu1(CodeHeapStateAnalytics_lock, Mutex::_no_safepoint_check_flag);
2783 out->cr();
2784 out->print_cr("__ CodeHeapStateAnalytics lock wait took %10.3f seconds _________", ts.seconds());
2785 out->cr();
2786
2787 if (aggregate) {
2788 // It is sufficient to hold the CodeCache_lock only for the aggregate step.
2789 // All other functions operate on aggregated data - except MethodNames, but that should be safe.
2790 // The separate CodeHeapStateAnalytics_lock protects the printing functions against
2791 // concurrent aggregate steps. Acquire this lock before acquiring the CodeCache_lock.
2792 // CodeHeapStateAnalytics_lock could be held by a concurrent thread for a long time,
2793 // leading to an unnecessarily long hold time of the CodeCache_lock.
2794 ts.update(); // record starting point
2795 MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
2796 out->cr();
2797 out->print_cr("__ CodeCache lock wait took %10.3f seconds _________", ts.seconds());
2798 out->cr();
2799
2800 ts.update(); // record starting point
2801 CodeCache::aggregate(out, granularity);
2802 out->cr();
2803 out->print_cr("__ CodeCache lock hold took %10.3f seconds _________", ts.seconds());
2804 out->cr();
2805 }
2806
2807 if (usedSpace) CodeCache::print_usedSpace(out);
2808 if (freeSpace) CodeCache::print_freeSpace(out);
2809 if (methodCount) CodeCache::print_count(out);
2810 if (methodSpace) CodeCache::print_space(out);
2811 if (methodAge) CodeCache::print_age(out);
2812 if (methodNames) CodeCache::print_names(out);
2813 if (discard) CodeCache::discard(out);
2814
2815 out->cr();
2816 out->print_cr("__ CodeHeapStateAnalytics total duration %10.3f seconds _________", ts_total.seconds());
2817 out->cr();
2818 }
|
1 /*
2 * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
2727 out->print_cr(" Committed size : " SIZE_FORMAT_W(7) " KB", CodeCache::capacity() / K);
2728 out->print_cr(" Unallocated capacity : " SIZE_FORMAT_W(7) " KB", CodeCache::unallocated_capacity() / K);
2729 out->cr();
2730
2731 out->cr();
2732 out->print_cr("CodeCache cleaning overview");
2733 out->print_cr("--------------------------------------------------------");
2734 out->cr();
2735 NMethodSweeper::print(out);
2736 out->print_cr("--------------------------------------------------------");
2737 out->cr();
2738 }
2739
2740 // Note: tty_lock must not be held upon entry to this function.
2741 // Print functions called from herein do "micro-locking" on tty_lock.
2742 // That's a tradeoff which keeps together important blocks of output.
2743 // At the same time, continuous tty_lock hold time is kept in check,
2744 // preventing concurrently printing threads from stalling a long time.
2745 void CompileBroker::print_heapinfo(outputStream* out, const char* function, size_t granularity) {
2746 TimeStamp ts_total;
2747 TimeStamp ts_global;
2748 TimeStamp ts;
2749
2750 bool allFun = !strcmp(function, "all");
2751 bool aggregate = !strcmp(function, "aggregate") || !strcmp(function, "analyze") || allFun;
2752 bool usedSpace = !strcmp(function, "UsedSpace") || allFun;
2753 bool freeSpace = !strcmp(function, "FreeSpace") || allFun;
2754 bool methodCount = !strcmp(function, "MethodCount") || allFun;
2755 bool methodSpace = !strcmp(function, "MethodSpace") || allFun;
2756 bool methodAge = !strcmp(function, "MethodAge") || allFun;
2757 bool methodNames = !strcmp(function, "MethodNames") || allFun;
2758 bool discard = !strcmp(function, "discard") || allFun;
2759
2760 if (out == NULL) {
2761 out = tty;
2762 }
2763
2764 if (!(aggregate || usedSpace || freeSpace || methodCount || methodSpace || methodAge || methodNames || discard)) {
2765 out->print_cr("\n__ CodeHeapStateAnalytics: Function %s is not supported", function);
2766 out->cr();
2767 return;
2768 }
2769
2770 ts_total.update(); // record starting point
2771
2772 if (aggregate) {
2773 print_info(out);
2774 }
2775
2776 // We hold the CodeHeapStateAnalytics_lock all the time, from here until we leave this function.
2777 // That prevents another thread from destroying our view on the CodeHeap.
2778 // When we request individual parts of the analysis via the jcmd interface, it is possible
2779 // that in between another thread (another jcmd user or the vm running into CodeCache OOM)
2780 // updated the aggregated data. That's a tolerable tradeoff because we can't hold a lock
2781 // across user interaction.
2782 // Acquire this lock before acquiring the CodeCache_lock.
2783 // CodeHeapStateAnalytics_lock could be held by a concurrent thread for a long time,
2784 // leading to an unnecessarily long hold time of the CodeCache_lock.
2785 ts.update(); // record starting point
2786 MutexLockerEx mu1(CodeHeapStateAnalytics_lock, Mutex::_no_safepoint_check_flag);
2787 out->print_cr("\n__ CodeHeapStateAnalytics lock wait took %10.3f seconds _________\n", ts.seconds());
2788
2789 // If we serve an "allFun" call, it is beneficial to hold the CodeCache_lock
2790 // for the entire duration of aggregation and printing. That makes sure
2791 // we see a consistent picture and do not run into issues caused by
2792 // the CodeHeap being altered concurrently.
2793 Monitor* global_lock = allFun ? CodeCache_lock : NULL;
2794 Monitor* function_lock = allFun ? NULL : CodeCache_lock;
2795 ts_global.update(); // record starting point
2796 MutexLockerEx mu2(global_lock, Mutex::_no_safepoint_check_flag);
2797 if (global_lock != NULL) {
2798 out->print_cr("\n__ CodeCache (global) lock wait took %10.3f seconds _________\n", ts_global.seconds());
2799 ts_global.update(); // record starting point
2800 }
2801
2802 if (aggregate) {
2803 ts.update(); // record starting point
2804 MutexLockerEx mu3(function_lock, Mutex::_no_safepoint_check_flag);
2805 if (function_lock != NULL) {
2806 out->print_cr("\n__ CodeCache (function) lock wait took %10.3f seconds _________\n", ts.seconds());
2807 }
2808
2809 ts.update(); // record starting point
2810 CodeCache::aggregate(out, granularity);
2811 if (function_lock != NULL) {
2812 out->print_cr("\n__ CodeCache (function) lock hold took %10.3f seconds _________\n", ts.seconds());
2813 }
2814 }
2815
2816 if (usedSpace) CodeCache::print_usedSpace(out);
2817 if (freeSpace) CodeCache::print_freeSpace(out);
2818 if (methodCount) CodeCache::print_count(out);
2819 if (methodSpace) CodeCache::print_space(out);
2820 if (methodAge) CodeCache::print_age(out);
2821 if (methodNames) {
2822 // print_names() has shown to be sensitive to concurrent CodeHeap modifications.
2823 // Therefore, request the CodeCache_lock before calling...
2824 MutexLockerEx mu3(function_lock, Mutex::_no_safepoint_check_flag);
2825 CodeCache::print_names(out);
2826 }
2827 if (discard) CodeCache::discard(out);
2828
2829 if (global_lock != NULL) {
2830 out->print_cr("\n__ CodeCache (global) lock hold took %10.3f seconds _________\n", ts_global.seconds());
2831 }
2832 out->print_cr("\n__ CodeHeapStateAnalytics total duration %10.3f seconds _________\n", ts_total.seconds());
2833 }
|