72 // calculate committed as region_num * region_size (i.e., what we use |
72 // calculate committed as region_num * region_size (i.e., what we use |
73 // to calculate the used space now). This is something to consider |
73 // to calculate the used space now). This is something to consider |
74 // in the future. |
74 // in the future. |
75 // |
75 // |
76 // 3) Another decision that is again not straightforward is what is |
76 // 3) Another decision that is again not straightforward is what is |
77 // the max size that each memory pool can grow to. Right now, we set |
77 // the max size that each memory pool can grow to. One way to do this |
78 // that the committed size for the eden and the survivors and |
78 // would be to use the committed size for the max for the eden and |
79 // calculate the old gen max as follows (basically, it's a similar |
79 // survivors and calculate the old gen max as follows (basically, it's |
80 // pattern to what we use for the committed space, as described |
80 // a similar pattern to what we use for the committed space, as |
81 // above): |
81 // described above): |
82 // |
82 // |
83 // old_gen_max = overall_max - eden_max - survivor_max |
83 // old_gen_max = overall_max - eden_max - survivor_max |
|
84 // |
|
85 // Unfortunately, the above makes the max of each pool fluctuate over |
|
86 // time and, even though this is allowed according to the spec, it |
|
87 // broke several assumptions in the M&M framework (there were cases |
|
88 // where used would reach a value greater than max). So, for max we |
|
89 // use -1, which means "undefined" according to the spec. |
84 // |
90 // |
85 // 4) Now, there is a very subtle issue with all the above. The |
91 // 4) Now, there is a very subtle issue with all the above. The |
86 // framework will call get_memory_usage() on the three pools |
92 // framework will call get_memory_usage() on the three pools |
87 // asynchronously. As a result, each call might get a different value |
93 // asynchronously. As a result, each call might get a different value |
88 // for, say, survivor_num which will yield inconsistent values for |
94 // for, say, survivor_num which will yield inconsistent values for |
123 |
129 |
124 // Would only be called from subclasses. |
130 // Would only be called from subclasses. |
125 G1MemoryPoolSuper(G1CollectedHeap* g1h, |
131 G1MemoryPoolSuper(G1CollectedHeap* g1h, |
126 const char* name, |
132 const char* name, |
127 size_t init_size, |
133 size_t init_size, |
128 size_t max_size, |
|
129 bool support_usage_threshold); |
134 bool support_usage_threshold); |
130 |
135 |
131 // The reason why all the code is in static methods is so that it |
136 // The reason why all the code is in static methods is so that it |
132 // can be safely called from the constructors of the subclasses. |
137 // can be safely called from the constructors of the subclasses. |
133 |
138 |
|
139 static size_t undefined_max() { |
|
140 return (size_t) -1; |
|
141 } |
|
142 |
134 static size_t overall_committed(G1CollectedHeap* g1h) { |
143 static size_t overall_committed(G1CollectedHeap* g1h) { |
135 return g1h->capacity(); |
144 return g1h->capacity(); |
136 } |
145 } |
137 static size_t overall_used(G1CollectedHeap* g1h) { |
146 static size_t overall_used(G1CollectedHeap* g1h) { |
138 return g1h->used_unlocked(); |
147 return g1h->used_unlocked(); |
139 } |
148 } |
140 static size_t overall_max(G1CollectedHeap* g1h) { |
|
141 return g1h->g1_reserved_obj_bytes(); |
|
142 } |
|
143 |
149 |
144 static size_t eden_space_committed(G1CollectedHeap* g1h); |
150 static size_t eden_space_committed(G1CollectedHeap* g1h); |
145 static size_t eden_space_used(G1CollectedHeap* g1h); |
151 static size_t eden_space_used(G1CollectedHeap* g1h); |
146 static size_t eden_space_max(G1CollectedHeap* g1h); |
|
147 |
152 |
148 static size_t survivor_space_committed(G1CollectedHeap* g1h); |
153 static size_t survivor_space_committed(G1CollectedHeap* g1h); |
149 static size_t survivor_space_used(G1CollectedHeap* g1h); |
154 static size_t survivor_space_used(G1CollectedHeap* g1h); |
150 static size_t survivor_space_max(G1CollectedHeap* g1h); |
|
151 |
155 |
152 static size_t old_space_committed(G1CollectedHeap* g1h); |
156 static size_t old_space_committed(G1CollectedHeap* g1h); |
153 static size_t old_space_used(G1CollectedHeap* g1h); |
157 static size_t old_space_used(G1CollectedHeap* g1h); |
154 static size_t old_space_max(G1CollectedHeap* g1h); |
|
155 }; |
158 }; |
156 |
159 |
157 // Memory pool that represents the G1 eden. |
160 // Memory pool that represents the G1 eden. |
158 class G1EdenPool : public G1MemoryPoolSuper { |
161 class G1EdenPool : public G1MemoryPoolSuper { |
159 public: |
162 public: |
161 |
164 |
162 size_t used_in_bytes() { |
165 size_t used_in_bytes() { |
163 return eden_space_used(_g1h); |
166 return eden_space_used(_g1h); |
164 } |
167 } |
165 size_t max_size() const { |
168 size_t max_size() const { |
166 return eden_space_max(_g1h); |
169 return undefined_max(); |
167 } |
170 } |
168 MemoryUsage get_memory_usage(); |
171 MemoryUsage get_memory_usage(); |
169 }; |
172 }; |
170 |
173 |
171 // Memory pool that represents the G1 survivor. |
174 // Memory pool that represents the G1 survivor. |
175 |
178 |
176 size_t used_in_bytes() { |
179 size_t used_in_bytes() { |
177 return survivor_space_used(_g1h); |
180 return survivor_space_used(_g1h); |
178 } |
181 } |
179 size_t max_size() const { |
182 size_t max_size() const { |
180 return survivor_space_max(_g1h); |
183 return undefined_max(); |
181 } |
184 } |
182 MemoryUsage get_memory_usage(); |
185 MemoryUsage get_memory_usage(); |
183 }; |
186 }; |
184 |
187 |
185 // Memory pool that represents the G1 old gen. |
188 // Memory pool that represents the G1 old gen. |