24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "gc/g1/g1CollectedHeap.hpp" |
26 #include "gc/g1/g1CollectedHeap.hpp" |
27 #include "gc/g1/g1HeapTransition.hpp" |
27 #include "gc/g1/g1HeapTransition.hpp" |
28 #include "gc/g1/g1Policy.hpp" |
28 #include "gc/g1/g1Policy.hpp" |
29 #include "logging/log.hpp" |
29 #include "logging/logStream.hpp" |
30 #include "memory/metaspace.hpp" |
30 #include "memory/metaspace.hpp" |
31 |
31 |
32 G1HeapTransition::Data::Data(G1CollectedHeap* g1_heap) { |
32 G1HeapTransition::Data::Data(G1CollectedHeap* g1_heap) : |
33 _eden_length = g1_heap->eden_regions_count(); |
33 _eden_length(g1_heap->eden_regions_count()), |
34 _survivor_length = g1_heap->survivor_regions_count(); |
34 _survivor_length(g1_heap->survivor_regions_count()), |
35 _old_length = g1_heap->old_regions_count(); |
35 _old_length(g1_heap->old_regions_count()), |
36 _archive_length = g1_heap->archive_regions_count(); |
36 _archive_length(g1_heap->archive_regions_count()), |
37 _humongous_length = g1_heap->humongous_regions_count(); |
37 _humongous_length(g1_heap->humongous_regions_count()), |
|
38 _eden_length_per_node(NULL), |
|
39 _survivor_length_per_node(NULL) { |
|
40 |
|
41 uint node_count = G1NUMA::numa()->num_active_nodes(); |
|
42 |
|
43 if (node_count > 1) { |
|
44 LogTarget(Debug, gc, heap, numa) lt; |
|
45 |
|
46 if (lt.is_enabled()) { |
|
47 _eden_length_per_node = NEW_C_HEAP_ARRAY(uint, node_count, mtGC); |
|
48 _survivor_length_per_node = NEW_C_HEAP_ARRAY(uint, node_count, mtGC); |
|
49 |
|
50 for (uint i = 0; i < node_count; i++) { |
|
51 _eden_length_per_node[i] = g1_heap->eden_regions_count(i); |
|
52 _survivor_length_per_node[i] = g1_heap->survivor_regions_count(i); |
|
53 } |
|
54 } |
|
55 } |
|
56 } |
|
57 |
|
58 G1HeapTransition::Data::~Data() { |
|
59 FREE_C_HEAP_ARRAY(uint, _eden_length_per_node); |
|
60 FREE_C_HEAP_ARRAY(uint, _survivor_length_per_node); |
38 } |
61 } |
39 |
62 |
40 G1HeapTransition::G1HeapTransition(G1CollectedHeap* g1_heap) : _g1_heap(g1_heap), _before(g1_heap) { } |
63 G1HeapTransition::G1HeapTransition(G1CollectedHeap* g1_heap) : _g1_heap(g1_heap), _before(g1_heap) { } |
41 |
64 |
42 struct DetailedUsage : public StackObj { |
65 struct DetailedUsage : public StackObj { |
82 } |
105 } |
83 return false; |
106 return false; |
84 } |
107 } |
85 }; |
108 }; |
86 |
109 |
|
110 static void log_regions(const char* msg, size_t before_length, size_t after_length, size_t capacity, |
|
111 uint* before_per_node_length, uint* after_per_node_length) { |
|
112 LogTarget(Info, gc, heap) lt; |
|
113 |
|
114 if (lt.is_enabled()) { |
|
115 LogStream ls(lt); |
|
116 |
|
117 ls.print("%s regions: " SIZE_FORMAT "->" SIZE_FORMAT "(" SIZE_FORMAT ")", |
|
118 msg, before_length, after_length, capacity); |
|
119 // Not NULL only if gc+heap+numa at Debug level is enabled. |
|
120 if (before_per_node_length != NULL && after_per_node_length != NULL) { |
|
121 G1NUMA* numa = G1NUMA::numa(); |
|
122 uint num_nodes = numa->num_active_nodes(); |
|
123 const int* node_ids = numa->node_ids(); |
|
124 ls.print(" ("); |
|
125 for (uint i = 0; i < num_nodes; i++) { |
|
126 ls.print("%d: %u->%u", node_ids[i], before_per_node_length[i], after_per_node_length[i]); |
|
127 // Skip adding below if it is the last one. |
|
128 if (i != num_nodes - 1) { |
|
129 ls.print(", "); |
|
130 } |
|
131 } |
|
132 ls.print(")"); |
|
133 } |
|
134 ls.print_cr(""); |
|
135 } |
|
136 } |
|
137 |
87 void G1HeapTransition::print() { |
138 void G1HeapTransition::print() { |
88 Data after(_g1_heap); |
139 Data after(_g1_heap); |
89 |
140 |
90 size_t eden_capacity_length_after_gc = _g1_heap->policy()->young_list_target_length() - after._survivor_length; |
141 size_t eden_capacity_length_after_gc = _g1_heap->policy()->young_list_target_length() - after._survivor_length; |
91 size_t survivor_capacity_length_before_gc = _g1_heap->policy()->max_survivor_regions(); |
142 size_t survivor_capacity_length_before_gc = _g1_heap->policy()->max_survivor_regions(); |
104 after._archive_length, usage._archive_region_count); |
155 after._archive_length, usage._archive_region_count); |
105 assert(usage._humongous_region_count == after._humongous_length, "Expected humongous to be " SIZE_FORMAT " but was " SIZE_FORMAT, |
156 assert(usage._humongous_region_count == after._humongous_length, "Expected humongous to be " SIZE_FORMAT " but was " SIZE_FORMAT, |
106 after._humongous_length, usage._humongous_region_count); |
157 after._humongous_length, usage._humongous_region_count); |
107 } |
158 } |
108 |
159 |
109 log_info(gc, heap)("Eden regions: " SIZE_FORMAT "->" SIZE_FORMAT "(" SIZE_FORMAT ")", |
160 log_regions("Eden", _before._eden_length, after._eden_length, eden_capacity_length_after_gc, |
110 _before._eden_length, after._eden_length, eden_capacity_length_after_gc); |
161 _before._eden_length_per_node, after._eden_length_per_node); |
111 log_trace(gc, heap)(" Used: 0K, Waste: 0K"); |
162 log_trace(gc, heap)(" Used: 0K, Waste: 0K"); |
112 |
163 |
113 log_info(gc, heap)("Survivor regions: " SIZE_FORMAT "->" SIZE_FORMAT "(" SIZE_FORMAT ")", |
164 log_regions("Survivor", _before._survivor_length, after._survivor_length, survivor_capacity_length_before_gc, |
114 _before._survivor_length, after._survivor_length, survivor_capacity_length_before_gc); |
165 _before._survivor_length_per_node, after._survivor_length_per_node); |
115 log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", |
166 log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", |
116 usage._survivor_used / K, ((after._survivor_length * HeapRegion::GrainBytes) - usage._survivor_used) / K); |
167 usage._survivor_used / K, ((after._survivor_length * HeapRegion::GrainBytes) - usage._survivor_used) / K); |
117 |
168 |
118 log_info(gc, heap)("Old regions: " SIZE_FORMAT "->" SIZE_FORMAT, |
169 log_info(gc, heap)("Old regions: " SIZE_FORMAT "->" SIZE_FORMAT, |
119 _before._old_length, after._old_length); |
170 _before._old_length, after._old_length); |