1 /* 2 * Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 * 22 */ 23 24 #include "precompiled.hpp" 25 #include "gc_implementation/shenandoah/shenandoahMetrics.hpp" 26 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" 27 #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" 28 #include "gc_implementation/shenandoah/shenandoahFreeSet.hpp" 29 30 ShenandoahMetricsSnapshot::ShenandoahMetricsSnapshot() { 31 _heap = ShenandoahHeap::heap(); 32 } 33 34 void ShenandoahMetricsSnapshot::snap_before() { 35 _used_before = _heap->used(); 36 _if_before = _heap->free_set()->internal_fragmentation(); 37 _ef_before = _heap->free_set()->external_fragmentation(); 38 } 39 void ShenandoahMetricsSnapshot::snap_after() { 40 _used_after = _heap->used(); 41 _if_after = _heap->free_set()->internal_fragmentation(); 42 _ef_after = _heap->free_set()->external_fragmentation(); 43 } 44 45 bool ShenandoahMetricsSnapshot::is_good_progress() { 46 // Under the critical threshold? 47 size_t free_actual = _heap->free_set()->available(); 48 size_t free_expected = _heap->max_capacity() / 100 * ShenandoahCriticalFreeThreshold; 49 bool prog_free = free_actual >= free_expected; 50 log_info(gc, ergo)("%s progress for free space: " SIZE_FORMAT "%s, need " SIZE_FORMAT "%s", 51 prog_free ? "Good" : "Bad", 52 byte_size_in_proper_unit(free_actual), proper_unit_for_byte_size(free_actual), 53 byte_size_in_proper_unit(free_expected), proper_unit_for_byte_size(free_expected)); 54 if (!prog_free) { 55 return false; 56 } 57 58 // Freed up enough? 59 size_t progress_actual = (_used_before > _used_after) ? _used_before - _used_after : 0; 60 size_t progress_expected = ShenandoahHeapRegion::region_size_bytes(); 61 bool prog_used = progress_actual >= progress_expected; 62 log_info(gc, ergo)("%s progress for used space: " SIZE_FORMAT "%s, need " SIZE_FORMAT "%s", 63 prog_used ? "Good" : "Bad", 64 byte_size_in_proper_unit(progress_actual), proper_unit_for_byte_size(progress_actual), 65 byte_size_in_proper_unit(progress_expected), proper_unit_for_byte_size(progress_expected)); 66 if (prog_used) { 67 return true; 68 } 69 70 // Internal fragmentation is down? 71 double if_actual = _if_before - _if_after; 72 double if_expected = 0.01; // 1% should be enough 73 bool prog_if = if_actual >= if_expected; 74 log_info(gc, ergo)("%s progress for internal fragmentation: %.1f%%, need %.1f%%", 75 prog_if ? "Good" : "Bad", 76 if_actual * 100, if_expected * 100); 77 if (prog_if) { 78 return true; 79 } 80 81 // External fragmentation is down? 82 double ef_actual = _ef_before - _ef_after; 83 double ef_expected = 0.01; // 1% should be enough 84 bool prog_ef = ef_actual >= ef_expected; 85 log_info(gc, ergo)("%s progress for external fragmentation: %.1f%%, need %.1f%%", 86 prog_ef ? "Good" : "Bad", 87 ef_actual * 100, ef_expected * 100); 88 if (prog_ef) { 89 return true; 90 } 91 92 // Nothing good had happened. 93 return false; 94 }