/root/doris/be/src/util/jvm_metrics.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | #include "jvm_metrics.h" |
19 | | |
20 | | #include <util/jni-util.h> |
21 | | |
22 | | #include <functional> |
23 | | |
24 | | #include "common/config.h" |
25 | | #include "util/defer_op.h" |
26 | | #include "util/metrics.h" |
27 | | |
28 | | namespace doris { |
29 | | |
30 | | #define DEFINE_JVM_SIZE_BYTES_METRIC(name, type) \ |
31 | | DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(name##_##type, MetricUnit::BYTES, "", name, \ |
32 | | Labels({{"type", #type}})); |
33 | | |
34 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, max); |
35 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, committed); |
36 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_heap_size_bytes, used); |
37 | | |
38 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, used); |
39 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_non_heap_size_bytes, committed); |
40 | | |
41 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, used); |
42 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, peak_used); |
43 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_young_size_bytes, max); |
44 | | |
45 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, used); |
46 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, peak_used); |
47 | | DEFINE_JVM_SIZE_BYTES_METRIC(jvm_old_size_bytes, max); |
48 | | |
49 | | #define DEFINE_JVM_THREAD_METRIC(type) \ |
50 | | DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_thread_##type, MetricUnit::NOUNIT, "", jvm_thread, \ |
51 | | Labels({{"type", #type}})); |
52 | | |
53 | | DEFINE_JVM_THREAD_METRIC(count); |
54 | | DEFINE_JVM_THREAD_METRIC(peak_count); |
55 | | DEFINE_JVM_THREAD_METRIC(new_count); |
56 | | DEFINE_JVM_THREAD_METRIC(runnable_count); |
57 | | DEFINE_JVM_THREAD_METRIC(blocked_count); |
58 | | DEFINE_JVM_THREAD_METRIC(waiting_count); |
59 | | DEFINE_JVM_THREAD_METRIC(timed_waiting_count); |
60 | | DEFINE_JVM_THREAD_METRIC(terminated_count); |
61 | | |
62 | | DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_count, MetricUnit::NOUNIT, "", |
63 | | jvm_gc, |
64 | | Labels({{"name", "G1 Young generation Count"}, |
65 | | {"type", "count"}})); |
66 | | |
67 | | DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_young_generation_time_ms, MetricUnit::MILLISECONDS, |
68 | | "", jvm_gc, |
69 | | Labels({{"name", "G1 Young generation Time"}, |
70 | | {"type", "time"}})); |
71 | | |
72 | | DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_count, MetricUnit::NOUNIT, "", jvm_gc, |
73 | | Labels({{"name", "G1 Old generation Count"}, |
74 | | {"type", "count"}})); |
75 | | |
76 | | DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(jvm_gc_g1_old_generation_time_ms, MetricUnit::MILLISECONDS, "", |
77 | | jvm_gc, |
78 | | Labels({{"name", "G1 Old generation Time"}, |
79 | | {"type", "time"}})); |
80 | | |
81 | | const char* JvmMetrics::_s_hook_name = "jvm_metrics"; |
82 | | |
83 | 0 | JvmMetrics::JvmMetrics(MetricRegistry* registry, JNIEnv* env) { |
84 | 0 | DCHECK(registry != nullptr); |
85 | 0 | _registry = registry; |
86 | |
|
87 | 0 | _server_entity = _registry->register_entity("server"); |
88 | 0 | DCHECK(_server_entity != nullptr); |
89 | |
|
90 | 0 | do { |
91 | 0 | if (!doris::config::enable_jvm_monitor) { |
92 | 0 | break; |
93 | 0 | } |
94 | 0 | try { |
95 | 0 | Status st = _jvm_stats.init(env); |
96 | 0 | if (!st) { |
97 | 0 | LOG(WARNING) << "jvm Stats Init Fail. " << st.to_string(); |
98 | 0 | break; |
99 | 0 | } |
100 | 0 | } catch (...) { |
101 | 0 | LOG(WARNING) << "jvm Stats Throw Exception Init Fail."; |
102 | 0 | break; |
103 | 0 | } |
104 | 0 | if (!_jvm_stats.init_complete()) { |
105 | 0 | break; |
106 | 0 | } |
107 | 0 | _server_entity->register_hook(_s_hook_name, std::bind(&JvmMetrics::update, this)); |
108 | 0 | } while (false); |
109 | | |
110 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_max); |
111 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_committed); |
112 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_heap_size_bytes_used); |
113 | |
|
114 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_non_heap_size_bytes_used); |
115 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_non_heap_size_bytes_committed); |
116 | |
|
117 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_used); |
118 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_peak_used); |
119 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_young_size_bytes_max); |
120 | |
|
121 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_used); |
122 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_peak_used); |
123 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_old_size_bytes_max); |
124 | |
|
125 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_count); |
126 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_peak_count); |
127 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_new_count); |
128 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_runnable_count); |
129 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_blocked_count); |
130 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_waiting_count); |
131 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_timed_waiting_count); |
132 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_thread_terminated_count); |
133 | |
|
134 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_gc_g1_young_generation_count); |
135 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_gc_g1_young_generation_time_ms); |
136 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_gc_g1_old_generation_count); |
137 | 0 | INT_GAUGE_METRIC_REGISTER(_server_entity, jvm_gc_g1_old_generation_time_ms); |
138 | 0 | } |
139 | | |
140 | 0 | void JvmMetrics::update() { |
141 | 0 | static long fail_count = 0; |
142 | 0 | try { |
143 | 0 | Status st = _jvm_stats.refresh(this); |
144 | 0 | if (!st) { |
145 | 0 | fail_count++; |
146 | 0 | LOG(WARNING) << "Jvm Stats update Fail! " << st.to_string(); |
147 | 0 | } else { |
148 | 0 | fail_count = 0; |
149 | 0 | } |
150 | 0 | } catch (...) { |
151 | 0 | LOG(WARNING) << "Jvm Stats update throw Exception!"; |
152 | 0 | fail_count++; |
153 | 0 | } |
154 | | |
155 | | //When 30 consecutive exceptions occur, turn off jvm information collection. |
156 | 0 | if (fail_count >= 30) { |
157 | 0 | LOG(WARNING) << "Jvm Stats CLOSE!"; |
158 | 0 | _jvm_stats.set_complete(false); |
159 | 0 | _server_entity->deregister_hook(_s_hook_name); |
160 | |
|
161 | 0 | jvm_heap_size_bytes_max->set_value(0); |
162 | 0 | jvm_heap_size_bytes_committed->set_value(0); |
163 | 0 | jvm_heap_size_bytes_used->set_value(0); |
164 | |
|
165 | 0 | jvm_non_heap_size_bytes_used->set_value(0); |
166 | 0 | jvm_non_heap_size_bytes_committed->set_value(0); |
167 | |
|
168 | 0 | jvm_young_size_bytes_used->set_value(0); |
169 | 0 | jvm_young_size_bytes_peak_used->set_value(0); |
170 | 0 | jvm_young_size_bytes_max->set_value(0); |
171 | |
|
172 | 0 | jvm_old_size_bytes_used->set_value(0); |
173 | 0 | jvm_old_size_bytes_peak_used->set_value(0); |
174 | 0 | jvm_old_size_bytes_max->set_value(0); |
175 | |
|
176 | 0 | jvm_thread_count->set_value(0); |
177 | 0 | jvm_thread_peak_count->set_value(0); |
178 | 0 | jvm_thread_new_count->set_value(0); |
179 | 0 | jvm_thread_runnable_count->set_value(0); |
180 | 0 | jvm_thread_blocked_count->set_value(0); |
181 | 0 | jvm_thread_waiting_count->set_value(0); |
182 | 0 | jvm_thread_timed_waiting_count->set_value(0); |
183 | 0 | jvm_thread_terminated_count->set_value(0); |
184 | |
|
185 | 0 | jvm_gc_g1_young_generation_count->set_value(0); |
186 | 0 | jvm_gc_g1_young_generation_time_ms->set_value(0); |
187 | 0 | jvm_gc_g1_old_generation_count->set_value(0); |
188 | 0 | jvm_gc_g1_old_generation_time_ms->set_value(0); |
189 | 0 | } |
190 | 0 | } |
191 | | |
192 | 0 | Status JvmStats::init(JNIEnv* env) { |
193 | 0 | RETURN_IF_ERROR(JniUtil::GetGlobalClassRef(env, "java/lang/management/ManagementFactory", |
194 | 0 | &_managementFactoryClass)); |
195 | | |
196 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, _getMemoryMXBeanMethod, env, |
197 | 0 | GetStaticMethodID(_managementFactoryClass, "getMemoryMXBean", |
198 | 0 | "()Ljava/lang/management/MemoryMXBean;")); |
199 | | |
200 | 0 | RETURN_IF_ERROR(JniUtil::GetGlobalClassRef(env, "java/lang/management/MemoryUsage", |
201 | 0 | &_memoryUsageClass)); |
202 | | |
203 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, _getMemoryUsageUsedMethod, env, |
204 | 0 | GetMethodID(_memoryUsageClass, "getUsed", "()J")); |
205 | | |
206 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, _getMemoryUsageCommittedMethod, env, |
207 | 0 | GetMethodID(_memoryUsageClass, "getCommitted", "()J")); |
208 | | |
209 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, _getMemoryUsageMaxMethod, env, |
210 | 0 | GetMethodID(_memoryUsageClass, "getMax", "()J")); |
211 | | |
212 | 0 | RETURN_IF_ERROR(JniUtil::GetGlobalClassRef(env, "java/lang/management/MemoryMXBean", |
213 | 0 | &_memoryMXBeanClass)); |
214 | | |
215 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, _getHeapMemoryUsageMethod, env, |
216 | 0 | GetMethodID(_memoryMXBeanClass, "getHeapMemoryUsage", |
217 | 0 | "()Ljava/lang/management/MemoryUsage;")); |
218 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, _getNonHeapMemoryUsageMethod, env, |
219 | 0 | GetMethodID(_memoryMXBeanClass, "getNonHeapMemoryUsage", |
220 | 0 | "()Ljava/lang/management/MemoryUsage;")); |
221 | | |
222 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
223 | 0 | , _getMemoryPoolMXBeansMethod, env, |
224 | 0 | GetStaticMethodID(_managementFactoryClass, "getMemoryPoolMXBeans", |
225 | 0 | "()Ljava/util/List;")); |
226 | | |
227 | 0 | RETURN_IF_ERROR(JniUtil::GetGlobalClassRef(env, "java/util/List", &_listClass)); |
228 | | |
229 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, _getListSizeMethod, env, |
230 | 0 | GetMethodID(_listClass, "size", "()I")); |
231 | | |
232 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, _getListUseIndexMethod, env, |
233 | 0 | GetMethodID(_listClass, "get", "(I)Ljava/lang/Object;")); |
234 | | |
235 | 0 | RETURN_IF_ERROR(JniUtil::GetGlobalClassRef(env, "java/lang/management/MemoryPoolMXBean", |
236 | 0 | &_memoryPoolMXBeanClass)); |
237 | | |
238 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, _getMemoryPoolMXBeanUsageMethod, env, |
239 | 0 | GetMethodID(_memoryPoolMXBeanClass, "getUsage", |
240 | 0 | "()Ljava/lang/management/MemoryUsage;")); |
241 | | |
242 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, _getMemoryPollMXBeanPeakMethod, env, |
243 | 0 | GetMethodID(_memoryPoolMXBeanClass, "getPeakUsage", |
244 | 0 | "()Ljava/lang/management/MemoryUsage;")); |
245 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
246 | 0 | , _getMemoryPollMXBeanNameMethod, env, |
247 | 0 | GetMethodID(_memoryPoolMXBeanClass, "getName", "()Ljava/lang/String;")); |
248 | | |
249 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, _getThreadMXBeanMethod, env, |
250 | 0 | GetStaticMethodID(_managementFactoryClass, "getThreadMXBean", |
251 | 0 | "()Ljava/lang/management/ThreadMXBean;")); |
252 | | |
253 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
254 | 0 | , _getGarbageCollectorMXBeansMethod, env, |
255 | 0 | GetStaticMethodID(_managementFactoryClass, "getGarbageCollectorMXBeans", |
256 | 0 | "()Ljava/util/List;")); |
257 | | |
258 | 0 | RETURN_IF_ERROR(JniUtil::GetGlobalClassRef(env, "java/lang/management/GarbageCollectorMXBean", |
259 | 0 | &_garbageCollectorMXBeanClass)); |
260 | | |
261 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
262 | 0 | , _getGCNameMethod, env, |
263 | 0 | GetMethodID(_garbageCollectorMXBeanClass, "getName", "()Ljava/lang/String;")); |
264 | | |
265 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
266 | 0 | , _getGCCollectionCountMethod, env, |
267 | 0 | GetMethodID(_garbageCollectorMXBeanClass, "getCollectionCount", "()J")); |
268 | | |
269 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
270 | 0 | , _getGCCollectionTimeMethod, env, |
271 | 0 | GetMethodID(_garbageCollectorMXBeanClass, "getCollectionTime", "()J")); |
272 | | |
273 | 0 | RETURN_IF_ERROR(JniUtil::GetGlobalClassRef(env, "java/lang/management/ThreadMXBean", |
274 | 0 | &_threadMXBeanClass)); |
275 | | |
276 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, |
277 | | |
278 | 0 | _getAllThreadIdsMethod, env, |
279 | 0 | GetMethodID(_threadMXBeanClass, "getAllThreadIds", "()[J")); |
280 | | |
281 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, |
282 | | |
283 | 0 | _getThreadInfoMethod, env, |
284 | 0 | GetMethodID(_threadMXBeanClass, "getThreadInfo", |
285 | 0 | "([JI)[Ljava/lang/management/ThreadInfo;")); |
286 | | |
287 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(, |
288 | | |
289 | 0 | _getPeakThreadCountMethod, env, |
290 | 0 | GetMethodID(_threadMXBeanClass, "getPeakThreadCount", "()I")); |
291 | | |
292 | 0 | RETURN_IF_ERROR( |
293 | 0 | JniUtil::GetGlobalClassRef(env, "java/lang/management/ThreadInfo", &_threadInfoClass)); |
294 | | |
295 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
296 | 0 | , |
297 | | |
298 | 0 | _getThreadStateMethod, env, |
299 | 0 | GetMethodID(_threadInfoClass, "getThreadState", "()Ljava/lang/Thread$State;")); |
300 | | |
301 | 0 | RETURN_IF_ERROR(JniUtil::GetGlobalClassRef(env, "java/lang/Thread$State", &_threadStateClass)); |
302 | | |
303 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
304 | 0 | jfieldID, newThreadFieldID, env, |
305 | 0 | GetStaticFieldID(_threadStateClass, "NEW", "Ljava/lang/Thread$State;")); |
306 | | |
307 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
308 | 0 | jfieldID, runnableThreadFieldID, env, |
309 | 0 | GetStaticFieldID(_threadStateClass, "RUNNABLE", "Ljava/lang/Thread$State;")); |
310 | | |
311 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
312 | 0 | jfieldID, blockedThreadFieldID, env, |
313 | 0 | GetStaticFieldID(_threadStateClass, "BLOCKED", "Ljava/lang/Thread$State;")); |
314 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
315 | 0 | jfieldID, waitingThreadFieldID, env, |
316 | 0 | GetStaticFieldID(_threadStateClass, "WAITING", "Ljava/lang/Thread$State;")); |
317 | | |
318 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
319 | 0 | jfieldID, timedWaitingThreadFieldID, env, |
320 | 0 | GetStaticFieldID(_threadStateClass, "TIMED_WAITING", "Ljava/lang/Thread$State;")); |
321 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
322 | 0 | jfieldID, terminatedThreadFieldID, env, |
323 | 0 | GetStaticFieldID(_threadStateClass, "TERMINATED", "Ljava/lang/Thread$State;")); |
324 | | |
325 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jobject, newThreadStateObj, env, |
326 | 0 | GetStaticObjectField(_threadStateClass, newThreadFieldID)); |
327 | 0 | RETURN_IF_ERROR(JniUtil::LocalToGlobalRef(env, newThreadStateObj, &_newThreadStateObj)); |
328 | | |
329 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jobject, runnableThreadStateObj, env, |
330 | 0 | GetStaticObjectField(_threadStateClass, runnableThreadFieldID)); |
331 | 0 | RETURN_IF_ERROR( |
332 | 0 | JniUtil::LocalToGlobalRef(env, runnableThreadStateObj, &_runnableThreadStateObj)); |
333 | | |
334 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jobject, blockedThreadStateObj, env, |
335 | 0 | GetStaticObjectField(_threadStateClass, blockedThreadFieldID)); |
336 | 0 | RETURN_IF_ERROR(JniUtil::LocalToGlobalRef(env, blockedThreadStateObj, &_blockedThreadStateObj)); |
337 | | |
338 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jobject, waitingThreadStateObj, env, |
339 | 0 | GetStaticObjectField(_threadStateClass, waitingThreadFieldID)); |
340 | 0 | RETURN_IF_ERROR(JniUtil::LocalToGlobalRef(env, waitingThreadStateObj, &_waitingThreadStateObj)); |
341 | | |
342 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
343 | 0 | jobject, timedWaitingThreadStateObj, env, |
344 | 0 | GetStaticObjectField(_threadStateClass, timedWaitingThreadFieldID)); |
345 | 0 | RETURN_IF_ERROR(JniUtil::LocalToGlobalRef(env, timedWaitingThreadStateObj, |
346 | 0 | &_timedWaitingThreadStateObj)); |
347 | | |
348 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
349 | 0 | jobject, terminatedThreadStateObj, env, |
350 | 0 | GetStaticObjectField(_threadStateClass, terminatedThreadFieldID)); |
351 | 0 | RETURN_IF_ERROR( |
352 | 0 | JniUtil::LocalToGlobalRef(env, terminatedThreadStateObj, &_terminatedThreadStateObj)); |
353 | | |
354 | 0 | _init_complete = true; |
355 | |
|
356 | 0 | LOG(INFO) << "Start JVM monitoring."; |
357 | 0 | return Status::OK(); |
358 | 0 | } |
359 | | |
360 | 0 | Status JvmStats::refresh(JvmMetrics* jvm_metrics) const { |
361 | 0 | if (!_init_complete) { |
362 | 0 | return Status::InternalError("Jvm Stats not init complete."); |
363 | 0 | } |
364 | | |
365 | 0 | JNIEnv* env = nullptr; |
366 | 0 | RETURN_IF_ERROR(JniUtil::GetJNIEnv(&env)); |
367 | | |
368 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
369 | 0 | jobject, memoryMXBeanObj, env, |
370 | 0 | CallStaticObjectMethod(_managementFactoryClass, _getMemoryMXBeanMethod)); |
371 | | |
372 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
373 | 0 | jobject, heapMemoryUsageObj, env, |
374 | 0 | CallObjectMethod(memoryMXBeanObj, _getHeapMemoryUsageMethod)); |
375 | | |
376 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jlong, heapMemoryUsed, env, |
377 | 0 | CallLongMethod(heapMemoryUsageObj, _getMemoryUsageUsedMethod)); |
378 | | |
379 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
380 | 0 | jlong, heapMemoryCommitted, env, |
381 | 0 | CallLongMethod(heapMemoryUsageObj, _getMemoryUsageCommittedMethod)); |
382 | | |
383 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jlong, heapMemoryMax, env, |
384 | 0 | CallLongMethod(heapMemoryUsageObj, _getMemoryUsageMaxMethod)); |
385 | | |
386 | 0 | jvm_metrics->jvm_heap_size_bytes_used->set_value(heapMemoryUsed < 0 ? 0 : heapMemoryUsed); |
387 | 0 | jvm_metrics->jvm_heap_size_bytes_committed->set_value( |
388 | 0 | heapMemoryCommitted < 0 ? 0 : heapMemoryCommitted); |
389 | 0 | jvm_metrics->jvm_heap_size_bytes_max->set_value(heapMemoryMax < 0 ? 0 : heapMemoryMax); |
390 | |
|
391 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
392 | 0 | jobject, nonHeapMemoryUsageObj, env, |
393 | 0 | CallObjectMethod(memoryMXBeanObj, _getNonHeapMemoryUsageMethod)); |
394 | | |
395 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
396 | 0 | jlong, nonHeapMemoryCommitted, env, |
397 | 0 | CallLongMethod(nonHeapMemoryUsageObj, _getMemoryUsageCommittedMethod)); |
398 | | |
399 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION( |
400 | 0 | jlong, nonHeapMemoryUsed, env, |
401 | 0 | CallLongMethod(nonHeapMemoryUsageObj, _getMemoryUsageUsedMethod)); |
402 | | |
403 | 0 | jvm_metrics->jvm_non_heap_size_bytes_committed->set_value( |
404 | 0 | nonHeapMemoryCommitted < 0 ? 0 : nonHeapMemoryCommitted); |
405 | 0 | jvm_metrics->jvm_non_heap_size_bytes_used->set_value(nonHeapMemoryUsed < 0 ? 0 |
406 | 0 | : nonHeapMemoryUsed); |
407 | |
|
408 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
409 | 0 | jobject, memoryPoolMXBeansList, env, |
410 | 0 | CallStaticObjectMethod(_managementFactoryClass, _getMemoryPoolMXBeansMethod)); |
411 | | |
412 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jint, size, env, |
413 | 0 | CallIntMethod(memoryPoolMXBeansList, _getListSizeMethod)); |
414 | | |
415 | 0 | for (int i = 0; i < size; ++i) { |
416 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
417 | 0 | jobject, memoryPoolMXBean, env, |
418 | 0 | CallObjectMethod(memoryPoolMXBeansList, _getListUseIndexMethod, i)); |
419 | | |
420 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
421 | 0 | jobject, usageObject, env, |
422 | 0 | CallObjectMethod(memoryPoolMXBean, _getMemoryPoolMXBeanUsageMethod)); |
423 | | |
424 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jlong, used, env, |
425 | 0 | CallLongMethod(usageObject, _getMemoryUsageUsedMethod)); |
426 | | |
427 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jlong, max, env, |
428 | 0 | CallLongMethod(usageObject, _getMemoryUsageMaxMethod)); |
429 | | |
430 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
431 | 0 | jobject, peakUsageObject, env, |
432 | 0 | CallObjectMethod(memoryPoolMXBean, _getMemoryPollMXBeanPeakMethod)); |
433 | | |
434 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jlong, peakUsed, env, |
435 | 0 | CallLongMethod(peakUsageObject, _getMemoryUsageUsedMethod)); |
436 | | |
437 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
438 | 0 | jobject, name, env, |
439 | 0 | CallObjectMethod(memoryPoolMXBean, _getMemoryPollMXBeanNameMethod)); |
440 | | |
441 | 0 | const char* nameStr = env->GetStringUTFChars( |
442 | 0 | (jstring)name, nullptr); // GetStringUTFChars not throw exception |
443 | 0 | if (nameStr != nullptr) { |
444 | 0 | auto it = _memoryPoolName.find(nameStr); |
445 | 0 | if (it == _memoryPoolName.end()) { |
446 | 0 | continue; |
447 | 0 | } |
448 | 0 | if (it->second == memoryPoolNameEnum::YOUNG) { |
449 | 0 | jvm_metrics->jvm_young_size_bytes_used->set_value(used < 0 ? 0 : used); |
450 | 0 | jvm_metrics->jvm_young_size_bytes_peak_used->set_value(peakUsed < 0 ? 0 : peakUsed); |
451 | 0 | jvm_metrics->jvm_young_size_bytes_max->set_value(max < 0 ? 0 : max); |
452 | |
|
453 | 0 | } else if (it->second == memoryPoolNameEnum::OLD) { |
454 | 0 | jvm_metrics->jvm_old_size_bytes_used->set_value(used < 0 ? 0 : used); |
455 | 0 | jvm_metrics->jvm_old_size_bytes_peak_used->set_value(peakUsed < 0 ? 0 : peakUsed); |
456 | 0 | jvm_metrics->jvm_old_size_bytes_max->set_value(max < 0 ? 0 : max); |
457 | 0 | } |
458 | |
|
459 | 0 | env->ReleaseStringUTFChars((jstring)name, |
460 | 0 | nameStr); // ReleaseStringUTFChars not throw exception |
461 | 0 | } |
462 | 0 | } |
463 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
464 | 0 | jobject, threadMXBean, env, |
465 | 0 | CallStaticObjectMethod(_managementFactoryClass, _getThreadMXBeanMethod)); |
466 | | |
467 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
468 | 0 | jobject, threadIdsObject, env, CallObjectMethod(threadMXBean, _getAllThreadIdsMethod)); |
469 | | |
470 | 0 | auto threadIds = (jlongArray)threadIdsObject; |
471 | |
|
472 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jint, threadCount, env, GetArrayLength(threadIds)); |
473 | | |
474 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
475 | 0 | jobject, threadInfos, env, |
476 | 0 | CallObjectMethod(threadMXBean, _getThreadInfoMethod, (jlongArray)threadIds, 0)); |
477 | | |
478 | 0 | int threadsNew = 0, threadsRunnable = 0, threadsBlocked = 0, threadsWaiting = 0, |
479 | 0 | threadsTimedWaiting = 0, threadsTerminated = 0; |
480 | |
|
481 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jint, peakThreadCount, env, |
482 | 0 | CallIntMethod(threadMXBean, _getPeakThreadCountMethod)); |
483 | | |
484 | 0 | jvm_metrics->jvm_thread_peak_count->set_value(peakThreadCount < 0 ? 0 : peakThreadCount); |
485 | 0 | jvm_metrics->jvm_thread_count->set_value(threadCount < 0 ? 0 : threadCount); |
486 | |
|
487 | 0 | for (int i = 0; i < threadCount; i++) { |
488 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
489 | 0 | jobject, threadInfo, env, GetObjectArrayElement((jobjectArray)threadInfos, i)); |
490 | | |
491 | 0 | if (threadInfo == nullptr) { |
492 | 0 | continue; |
493 | 0 | } |
494 | | |
495 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
496 | 0 | jobject, threadState, env, CallObjectMethod(threadInfo, _getThreadStateMethod)); |
497 | | |
498 | | //IsSameObject not throw exception |
499 | 0 | if (env->IsSameObject(threadState, _newThreadStateObj)) { |
500 | 0 | threadsNew++; |
501 | 0 | } else if (env->IsSameObject(threadState, _runnableThreadStateObj)) { |
502 | 0 | threadsRunnable++; |
503 | 0 | } else if (env->IsSameObject(threadState, _blockedThreadStateObj)) { |
504 | 0 | threadsBlocked++; |
505 | 0 | } else if (env->IsSameObject(threadState, _waitingThreadStateObj)) { |
506 | 0 | threadsWaiting++; |
507 | 0 | } else if (env->IsSameObject(threadState, _timedWaitingThreadStateObj)) { |
508 | 0 | threadsTimedWaiting++; |
509 | 0 | } else if (env->IsSameObject(threadState, _terminatedThreadStateObj)) { |
510 | 0 | threadsTerminated++; |
511 | 0 | } |
512 | 0 | } |
513 | | |
514 | 0 | jvm_metrics->jvm_thread_new_count->set_value(threadsNew < 0 ? 0 : threadsNew); |
515 | 0 | jvm_metrics->jvm_thread_runnable_count->set_value(threadsRunnable < 0 ? 0 : threadsRunnable); |
516 | 0 | jvm_metrics->jvm_thread_blocked_count->set_value(threadsBlocked < 0 ? 0 : threadsBlocked); |
517 | 0 | jvm_metrics->jvm_thread_waiting_count->set_value(threadsWaiting < 0 ? 0 : threadsWaiting); |
518 | 0 | jvm_metrics->jvm_thread_timed_waiting_count->set_value( |
519 | 0 | threadsTimedWaiting < 0 ? 0 : threadsTimedWaiting); |
520 | 0 | jvm_metrics->jvm_thread_terminated_count->set_value(threadsTerminated < 0 ? 0 |
521 | 0 | : threadsTerminated); |
522 | |
|
523 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
524 | 0 | jobject, gcMXBeansList, env, |
525 | 0 | CallStaticObjectMethod(_managementFactoryClass, _getGarbageCollectorMXBeansMethod)); |
526 | | |
527 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jint, numCollectors, env, |
528 | 0 | CallIntMethod(gcMXBeansList, _getListSizeMethod)); |
529 | | |
530 | 0 | for (int i = 0; i < numCollectors; i++) { |
531 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF( |
532 | 0 | jobject, gcMXBean, env, CallObjectMethod(gcMXBeansList, _getListUseIndexMethod, i)); |
533 | | |
534 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION_DELETE_REF(jobject, gcName, env, |
535 | 0 | CallObjectMethod(gcMXBean, _getGCNameMethod)); |
536 | | |
537 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jlong, gcCollectionCount, env, |
538 | 0 | CallLongMethod(gcMXBean, _getGCCollectionCountMethod)); |
539 | | |
540 | 0 | JNI_CALL_METHOD_CHECK_EXCEPTION(jlong, gcCollectionTime, env, |
541 | 0 | CallLongMethod(gcMXBean, _getGCCollectionTimeMethod)); |
542 | | |
543 | 0 | const char* gcNameStr = env->GetStringUTFChars((jstring)gcName, NULL); |
544 | 0 | if (gcNameStr != nullptr) { |
545 | 0 | if (strcmp(gcNameStr, "G1 Young Generation") == 0) { |
546 | 0 | jvm_metrics->jvm_gc_g1_young_generation_count->set_value(gcCollectionCount); |
547 | 0 | jvm_metrics->jvm_gc_g1_young_generation_time_ms->set_value(gcCollectionTime); |
548 | |
|
549 | 0 | } else { |
550 | 0 | jvm_metrics->jvm_gc_g1_old_generation_count->set_value(gcCollectionCount); |
551 | 0 | jvm_metrics->jvm_gc_g1_old_generation_time_ms->set_value(gcCollectionTime); |
552 | 0 | } |
553 | |
|
554 | 0 | env->ReleaseStringUTFChars((jstring)gcName, gcNameStr); |
555 | 0 | } |
556 | 0 | } |
557 | | |
558 | 0 | return Status::OK(); |
559 | 0 | } |
560 | 0 | JvmStats::~JvmStats() { |
561 | 0 | if (!_init_complete) { |
562 | 0 | return; |
563 | 0 | } |
564 | 0 | try { |
565 | 0 | JNIEnv* env = nullptr; |
566 | 0 | Status st = JniUtil::GetJNIEnv(&env); |
567 | 0 | if (!st.ok()) { |
568 | 0 | return; |
569 | 0 | } |
570 | 0 | env->DeleteGlobalRef(_managementFactoryClass); |
571 | 0 | env->DeleteGlobalRef(_memoryUsageClass); |
572 | 0 | env->DeleteGlobalRef(_memoryMXBeanClass); |
573 | 0 | env->DeleteGlobalRef(_listClass); |
574 | 0 | env->DeleteGlobalRef(_memoryPoolMXBeanClass); |
575 | 0 | env->DeleteGlobalRef(_threadMXBeanClass); |
576 | 0 | env->DeleteGlobalRef(_threadInfoClass); |
577 | 0 | env->DeleteGlobalRef(_threadStateClass); |
578 | 0 | env->DeleteGlobalRef(_garbageCollectorMXBeanClass); |
579 | |
|
580 | 0 | env->DeleteGlobalRef(_newThreadStateObj); |
581 | 0 | env->DeleteGlobalRef(_runnableThreadStateObj); |
582 | 0 | env->DeleteGlobalRef(_blockedThreadStateObj); |
583 | 0 | env->DeleteGlobalRef(_waitingThreadStateObj); |
584 | 0 | env->DeleteGlobalRef(_timedWaitingThreadStateObj); |
585 | 0 | env->DeleteGlobalRef(_terminatedThreadStateObj); |
586 | |
|
587 | 0 | } catch (...) { |
588 | | // In order to exit more gracefully, we catch the exception here. |
589 | 0 | } |
590 | 0 | } |
591 | | |
592 | | } // namespace doris |