Fri, 29 Apr 2011 14:59:04 -0400
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
Summary: We should only undirty cards after we decide that they are not on a young region, not before. The fix also includes improvements to the verify_dirty_region() method which print out which cards were not found dirty.
Reviewed-by: johnc, brutisso
jmasa@2821 | 1 | /* |
jmasa@2821 | 2 | * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. |
jmasa@2821 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
jmasa@2821 | 4 | * |
jmasa@2821 | 5 | * This code is free software; you can redistribute it and/or modify it |
jmasa@2821 | 6 | * under the terms of the GNU General Public License version 2 only, as |
jmasa@2821 | 7 | * published by the Free Software Foundation. |
jmasa@2821 | 8 | * |
jmasa@2821 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
jmasa@2821 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
jmasa@2821 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
jmasa@2821 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
jmasa@2821 | 13 | * accompanied this code). |
jmasa@2821 | 14 | * |
jmasa@2821 | 15 | * You should have received a copy of the GNU General Public License version |
jmasa@2821 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
jmasa@2821 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
jmasa@2821 | 18 | * |
jmasa@2821 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
jmasa@2821 | 20 | * or visit www.oracle.com if you need additional information or have any |
jmasa@2821 | 21 | * questions. |
jmasa@2821 | 22 | * |
jmasa@2821 | 23 | */ |
jmasa@2821 | 24 | |
jmasa@2821 | 25 | #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1MONITORINGSUPPORT_HPP |
jmasa@2821 | 26 | #define SHARE_VM_GC_IMPLEMENTATION_G1_G1MONITORINGSUPPORT_HPP |
jmasa@2821 | 27 | |
jmasa@2821 | 28 | #include "gc_implementation/shared/hSpaceCounters.hpp" |
jmasa@2821 | 29 | |
jmasa@2821 | 30 | class G1CollectedHeap; |
jmasa@2821 | 31 | class G1SpaceMonitoringSupport; |
jmasa@2821 | 32 | |
jmasa@2821 | 33 | // Class for monitoring logical spaces in G1. |
jmasa@2821 | 34 | // G1 defines a set of regions as a young |
jmasa@2821 | 35 | // collection (analogous to a young generation). |
jmasa@2821 | 36 | // The young collection is a logical generation |
jmasa@2821 | 37 | // with no fixed chunk (see space.hpp) reflecting |
jmasa@2821 | 38 | // the address space for the generation. In addition |
jmasa@2821 | 39 | // to the young collection there is its complement |
jmasa@2821 | 40 | // the non-young collection that is simply the regions |
jmasa@2821 | 41 | // not in the young collection. The non-young collection |
jmasa@2821 | 42 | // is treated here as a logical old generation only |
jmasa@2821 | 43 | // because the monitoring tools expect a generational |
jmasa@2821 | 44 | // heap. The monitoring tools expect that a Space |
jmasa@2821 | 45 | // (see space.hpp) exists that describe the |
jmasa@2821 | 46 | // address space of young collection and non-young |
jmasa@2821 | 47 | // collection and such a view is provided here. |
jmasa@2821 | 48 | // |
jmasa@2821 | 49 | // This class provides interfaces to access |
jmasa@2821 | 50 | // the value of variables for the young collection |
jmasa@2821 | 51 | // that include the "capacity" and "used" of the |
jmasa@2821 | 52 | // young collection along with constant values |
jmasa@2821 | 53 | // for the minimum and maximum capacities for |
jmasa@2821 | 54 | // the logical spaces. Similarly for the non-young |
jmasa@2821 | 55 | // collection. |
jmasa@2821 | 56 | // |
jmasa@2821 | 57 | // Also provided are counters for G1 concurrent collections |
jmasa@2821 | 58 | // and stop-the-world full heap collecitons. |
jmasa@2821 | 59 | // |
jmasa@2821 | 60 | // Below is a description of how "used" and "capactiy" |
jmasa@2821 | 61 | // (or committed) is calculated for the logical spaces. |
jmasa@2821 | 62 | // |
jmasa@2821 | 63 | // 1) The used space calculation for a pool is not necessarily |
jmasa@2821 | 64 | // independent of the others. We can easily get from G1 the overall |
jmasa@2821 | 65 | // used space in the entire heap, the number of regions in the young |
jmasa@2821 | 66 | // generation (includes both eden and survivors), and the number of |
jmasa@2821 | 67 | // survivor regions. So, from that we calculate: |
jmasa@2821 | 68 | // |
jmasa@2821 | 69 | // survivor_used = survivor_num * region_size |
jmasa@2821 | 70 | // eden_used = young_region_num * region_size - survivor_used |
jmasa@2821 | 71 | // old_gen_used = overall_used - eden_used - survivor_used |
jmasa@2821 | 72 | // |
jmasa@2821 | 73 | // Note that survivor_used and eden_used are upper bounds. To get the |
jmasa@2821 | 74 | // actual value we would have to iterate over the regions and add up |
jmasa@2821 | 75 | // ->used(). But that'd be expensive. So, we'll accept some lack of |
jmasa@2821 | 76 | // accuracy for those two. But, we have to be careful when calculating |
jmasa@2821 | 77 | // old_gen_used, in case we subtract from overall_used more then the |
jmasa@2821 | 78 | // actual number and our result goes negative. |
jmasa@2821 | 79 | // |
jmasa@2821 | 80 | // 2) Calculating the used space is straightforward, as described |
jmasa@2821 | 81 | // above. However, how do we calculate the committed space, given that |
jmasa@2821 | 82 | // we allocate space for the eden, survivor, and old gen out of the |
jmasa@2821 | 83 | // same pool of regions? One way to do this is to use the used value |
jmasa@2821 | 84 | // as also the committed value for the eden and survivor spaces and |
jmasa@2821 | 85 | // then calculate the old gen committed space as follows: |
jmasa@2821 | 86 | // |
jmasa@2821 | 87 | // old_gen_committed = overall_committed - eden_committed - survivor_committed |
jmasa@2821 | 88 | // |
jmasa@2821 | 89 | // Maybe a better way to do that would be to calculate used for eden |
jmasa@2821 | 90 | // and survivor as a sum of ->used() over their regions and then |
jmasa@2821 | 91 | // calculate committed as region_num * region_size (i.e., what we use |
jmasa@2821 | 92 | // to calculate the used space now). This is something to consider |
jmasa@2821 | 93 | // in the future. |
jmasa@2821 | 94 | // |
jmasa@2821 | 95 | // 3) Another decision that is again not straightforward is what is |
jmasa@2821 | 96 | // the max size that each memory pool can grow to. One way to do this |
jmasa@2821 | 97 | // would be to use the committed size for the max for the eden and |
jmasa@2821 | 98 | // survivors and calculate the old gen max as follows (basically, it's |
jmasa@2821 | 99 | // a similar pattern to what we use for the committed space, as |
jmasa@2821 | 100 | // described above): |
jmasa@2821 | 101 | // |
jmasa@2821 | 102 | // old_gen_max = overall_max - eden_max - survivor_max |
jmasa@2821 | 103 | // |
jmasa@2821 | 104 | // Unfortunately, the above makes the max of each pool fluctuate over |
jmasa@2821 | 105 | // time and, even though this is allowed according to the spec, it |
jmasa@2821 | 106 | // broke several assumptions in the M&M framework (there were cases |
jmasa@2821 | 107 | // where used would reach a value greater than max). So, for max we |
jmasa@2821 | 108 | // use -1, which means "undefined" according to the spec. |
jmasa@2821 | 109 | // |
jmasa@2821 | 110 | // 4) Now, there is a very subtle issue with all the above. The |
jmasa@2821 | 111 | // framework will call get_memory_usage() on the three pools |
jmasa@2821 | 112 | // asynchronously. As a result, each call might get a different value |
jmasa@2821 | 113 | // for, say, survivor_num which will yield inconsistent values for |
jmasa@2821 | 114 | // eden_used, survivor_used, and old_gen_used (as survivor_num is used |
jmasa@2821 | 115 | // in the calculation of all three). This would normally be |
jmasa@2821 | 116 | // ok. However, it's possible that this might cause the sum of |
jmasa@2821 | 117 | // eden_used, survivor_used, and old_gen_used to go over the max heap |
jmasa@2821 | 118 | // size and this seems to sometimes cause JConsole (and maybe other |
jmasa@2821 | 119 | // clients) to get confused. There's not a really an easy / clean |
jmasa@2821 | 120 | // solution to this problem, due to the asynchrounous nature of the |
jmasa@2821 | 121 | // framework. |
jmasa@2821 | 122 | |
jmasa@2821 | 123 | class G1MonitoringSupport : public CHeapObj { |
jmasa@2821 | 124 | G1CollectedHeap* _g1h; |
jmasa@2821 | 125 | VirtualSpace* _g1_storage_addr; |
jmasa@2821 | 126 | |
jmasa@2821 | 127 | // jstat performance counters |
jmasa@2821 | 128 | // incremental collections both fully and partially young |
jmasa@2821 | 129 | CollectorCounters* _incremental_collection_counters; |
jmasa@2821 | 130 | // full stop-the-world collections |
jmasa@2821 | 131 | CollectorCounters* _full_collection_counters; |
jmasa@2821 | 132 | // young collection set counters. The _eden_counters, |
jmasa@2821 | 133 | // _from_counters, and _to_counters are associated with |
jmasa@2821 | 134 | // this "generational" counter. |
jmasa@2821 | 135 | GenerationCounters* _young_collection_counters; |
jmasa@2821 | 136 | // non-young collection set counters. The _old_space_counters |
jmasa@2821 | 137 | // below are associated with this "generational" counter. |
jmasa@2821 | 138 | GenerationCounters* _non_young_collection_counters; |
jmasa@2821 | 139 | // Counters for the capacity and used for |
jmasa@2821 | 140 | // the whole heap |
jmasa@2821 | 141 | HSpaceCounters* _old_space_counters; |
jmasa@2821 | 142 | // the young collection |
jmasa@2821 | 143 | HSpaceCounters* _eden_counters; |
jmasa@2821 | 144 | // the survivor collection (only one, _to_counters, is actively used) |
jmasa@2821 | 145 | HSpaceCounters* _from_counters; |
jmasa@2821 | 146 | HSpaceCounters* _to_counters; |
jmasa@2821 | 147 | |
jmasa@2821 | 148 | // It returns x - y if x > y, 0 otherwise. |
jmasa@2821 | 149 | // As described in the comment above, some of the inputs to the |
jmasa@2821 | 150 | // calculations we have to do are obtained concurrently and hence |
jmasa@2821 | 151 | // may be inconsistent with each other. So, this provides a |
jmasa@2821 | 152 | // defensive way of performing the subtraction and avoids the value |
jmasa@2821 | 153 | // going negative (which would mean a very large result, given that |
jmasa@2821 | 154 | // the parameter are size_t). |
jmasa@2821 | 155 | static size_t subtract_up_to_zero(size_t x, size_t y) { |
jmasa@2821 | 156 | if (x > y) { |
jmasa@2821 | 157 | return x - y; |
jmasa@2821 | 158 | } else { |
jmasa@2821 | 159 | return 0; |
jmasa@2821 | 160 | } |
jmasa@2821 | 161 | } |
jmasa@2821 | 162 | |
jmasa@2821 | 163 | public: |
jmasa@2821 | 164 | G1MonitoringSupport(G1CollectedHeap* g1h, VirtualSpace* g1_storage_addr); |
jmasa@2821 | 165 | |
jmasa@2821 | 166 | G1CollectedHeap* g1h() { return _g1h; } |
jmasa@2821 | 167 | VirtualSpace* g1_storage_addr() { return _g1_storage_addr; } |
jmasa@2821 | 168 | |
jmasa@2821 | 169 | // Performance Counter accessors |
jmasa@2821 | 170 | void update_counters(); |
jmasa@2821 | 171 | void update_eden_counters(); |
jmasa@2821 | 172 | |
jmasa@2821 | 173 | CollectorCounters* incremental_collection_counters() { |
jmasa@2821 | 174 | return _incremental_collection_counters; |
jmasa@2821 | 175 | } |
jmasa@2821 | 176 | CollectorCounters* full_collection_counters() { |
jmasa@2821 | 177 | return _full_collection_counters; |
jmasa@2821 | 178 | } |
jmasa@2821 | 179 | GenerationCounters* non_young_collection_counters() { |
jmasa@2821 | 180 | return _non_young_collection_counters; |
jmasa@2821 | 181 | } |
jmasa@2821 | 182 | HSpaceCounters* old_space_counters() { return _old_space_counters; } |
jmasa@2821 | 183 | HSpaceCounters* eden_counters() { return _eden_counters; } |
jmasa@2821 | 184 | HSpaceCounters* from_counters() { return _from_counters; } |
jmasa@2821 | 185 | HSpaceCounters* to_counters() { return _to_counters; } |
jmasa@2821 | 186 | |
jmasa@2821 | 187 | // Monitoring support used by |
jmasa@2821 | 188 | // MemoryService |
jmasa@2821 | 189 | // jstat counters |
jmasa@2821 | 190 | size_t overall_committed(); |
jmasa@2821 | 191 | size_t overall_used(); |
jmasa@2821 | 192 | |
jmasa@2821 | 193 | size_t eden_space_committed(); |
jmasa@2821 | 194 | size_t eden_space_used(); |
jmasa@2821 | 195 | |
jmasa@2821 | 196 | size_t survivor_space_committed(); |
jmasa@2821 | 197 | size_t survivor_space_used(); |
jmasa@2821 | 198 | |
jmasa@2821 | 199 | size_t old_space_committed(); |
jmasa@2821 | 200 | size_t old_space_used(); |
jmasa@2821 | 201 | }; |
jmasa@2821 | 202 | |
jmasa@2821 | 203 | #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1MONITORINGSUPPORT_HPP |