|
1 /* |
|
2 * Copyright (c) 2016, 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 * |
|
23 */ |
|
24 |
|
25 #include "precompiled.hpp" |
|
26 #include "gc/g1/g1CollectedHeap.hpp" |
|
27 #include "gc/g1/g1HeapTransition.hpp" |
|
28 #include "gc/g1/g1Policy.hpp" |
|
29 #include "logging/log.hpp" |
|
30 #include "memory/metaspace.hpp" |
|
31 |
|
32 G1HeapTransition::Data::Data(G1CollectedHeap* g1_heap) { |
|
33 _eden_length = g1_heap->eden_regions_count(); |
|
34 _survivor_length = g1_heap->survivor_regions_count(); |
|
35 _old_length = g1_heap->old_regions_count(); |
|
36 _humongous_length = g1_heap->humongous_regions_count(); |
|
37 _metaspace_used_bytes = MetaspaceAux::used_bytes(); |
|
38 } |
|
39 |
|
40 G1HeapTransition::G1HeapTransition(G1CollectedHeap* g1_heap) : _g1_heap(g1_heap), _before(g1_heap) { } |
|
41 |
|
42 struct DetailedUsage : public StackObj { |
|
43 size_t _eden_used; |
|
44 size_t _survivor_used; |
|
45 size_t _old_used; |
|
46 size_t _humongous_used; |
|
47 |
|
48 size_t _eden_region_count; |
|
49 size_t _survivor_region_count; |
|
50 size_t _old_region_count; |
|
51 size_t _humongous_region_count; |
|
52 |
|
53 DetailedUsage() : |
|
54 _eden_used(0), _survivor_used(0), _old_used(0), _humongous_used(0), |
|
55 _eden_region_count(0), _survivor_region_count(0), _old_region_count(0), _humongous_region_count(0) {} |
|
56 }; |
|
57 |
|
58 class DetailedUsageClosure: public HeapRegionClosure { |
|
59 public: |
|
60 DetailedUsage _usage; |
|
61 bool doHeapRegion(HeapRegion* r) { |
|
62 if (r->is_old()) { |
|
63 _usage._old_used += r->used(); |
|
64 _usage._old_region_count++; |
|
65 } else if (r->is_survivor()) { |
|
66 _usage._survivor_used += r->used(); |
|
67 _usage._survivor_region_count++; |
|
68 } else if (r->is_eden()) { |
|
69 _usage._eden_used += r->used(); |
|
70 _usage._eden_region_count++; |
|
71 } else if (r->is_humongous()) { |
|
72 _usage._humongous_used += r->used(); |
|
73 _usage._humongous_region_count++; |
|
74 } else { |
|
75 assert(r->used() == 0, "Expected used to be 0 but it was " SIZE_FORMAT, r->used()); |
|
76 } |
|
77 return false; |
|
78 } |
|
79 }; |
|
80 |
|
81 void G1HeapTransition::print() { |
|
82 Data after(_g1_heap); |
|
83 |
|
84 size_t eden_capacity_length_after_gc = _g1_heap->g1_policy()->young_list_target_length() - after._survivor_length; |
|
85 size_t survivor_capacity_length_after_gc = _g1_heap->g1_policy()->max_survivor_regions(); |
|
86 |
|
87 DetailedUsage usage; |
|
88 if (log_is_enabled(Trace, gc, heap)) { |
|
89 DetailedUsageClosure blk; |
|
90 _g1_heap->heap_region_iterate(&blk); |
|
91 usage = blk._usage; |
|
92 assert(usage._eden_region_count == 0, "Expected no eden regions, but got " SIZE_FORMAT, usage._eden_region_count); |
|
93 assert(usage._survivor_region_count == after._survivor_length, "Expected survivors to be " SIZE_FORMAT " but was " SIZE_FORMAT, |
|
94 after._survivor_length, usage._survivor_region_count); |
|
95 assert(usage._old_region_count == after._old_length, "Expected old to be " SIZE_FORMAT " but was " SIZE_FORMAT, |
|
96 after._old_length, usage._old_region_count); |
|
97 assert(usage._humongous_region_count == after._humongous_length, "Expected humongous to be " SIZE_FORMAT " but was " SIZE_FORMAT, |
|
98 after._humongous_length, usage._humongous_region_count); |
|
99 } |
|
100 |
|
101 log_info(gc, heap)("Eden regions: " SIZE_FORMAT "->" SIZE_FORMAT "(" SIZE_FORMAT ")", |
|
102 _before._eden_length, after._eden_length, eden_capacity_length_after_gc); |
|
103 log_trace(gc, heap)(" Used: 0K, Waste: 0K"); |
|
104 |
|
105 log_info(gc, heap)("Survivor regions: " SIZE_FORMAT "->" SIZE_FORMAT "(" SIZE_FORMAT ")", |
|
106 _before._survivor_length, after._survivor_length, survivor_capacity_length_after_gc); |
|
107 log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", |
|
108 usage._survivor_used / K, ((after._survivor_length * HeapRegion::GrainBytes) - usage._survivor_used) / K); |
|
109 |
|
110 log_info(gc, heap)("Old regions: " SIZE_FORMAT "->" SIZE_FORMAT, |
|
111 _before._old_length, after._old_length); |
|
112 log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", |
|
113 usage._old_used / K, ((after._old_length * HeapRegion::GrainBytes) - usage._old_used) / K); |
|
114 |
|
115 log_info(gc, heap)("Humongous regions: " SIZE_FORMAT "->" SIZE_FORMAT, |
|
116 _before._humongous_length, after._humongous_length); |
|
117 log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", |
|
118 usage._humongous_used / K, ((after._humongous_length * HeapRegion::GrainBytes) - usage._humongous_used) / K); |
|
119 |
|
120 MetaspaceAux::print_metaspace_change(_before._metaspace_used_bytes); |
|
121 } |