Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/jcl/common/mgmtgc.c
6000 views
1
/*******************************************************************************
2
* Copyright (c) 1998, 2018 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
#include "jni.h"
24
#include "j9.h"
25
#include "jclglob.h"
26
#include "jclprots.h"
27
#include "mgmtinit.h"
28
#include "jniidcacheinit.h"
29
30
typedef enum {
31
FIELD_TOTAL_GC_TIME,
32
FIELD_LASTGC_START_TIME,
33
FIELD_LASTGC_END_TIME,
34
FIELD_COLLECTION_COUNT,
35
FIELD_MEMORY_USED,
36
FIELD_TOTAL_MEMORY_FREED,
37
FIELD_TOTAL_COMPACTS
38
} GarbageCollectorField;
39
40
#define GC_FIELD_TOTAL_GC_TIME
41
42
static UDATA getIndexFromCollectorID(J9JavaLangManagementData *mgmt, UDATA id);
43
static jlong getCollectorField(JNIEnv *env, jint id, GarbageCollectorField field);
44
45
jlong JNICALL
46
Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getCollectionCountImpl(JNIEnv *env, jobject beanInstance, jint id)
47
{
48
return getCollectorField(env, id, FIELD_COLLECTION_COUNT);
49
}
50
51
jlong JNICALL
52
Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getCollectionTimeImpl(JNIEnv *env, jobject beanInstance, jint id)
53
{
54
return getCollectorField(env, id, FIELD_TOTAL_GC_TIME);
55
}
56
57
jlong JNICALL
58
Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getLastCollectionStartTimeImpl(JNIEnv *env, jobject beanInstance, jint id)
59
{
60
return getCollectorField(env, id, FIELD_LASTGC_START_TIME);
61
}
62
63
jlong JNICALL
64
Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getLastCollectionEndTimeImpl(JNIEnv *env, jobject beanInstance, jint id)
65
{
66
return getCollectorField(env, id, FIELD_LASTGC_END_TIME);
67
}
68
69
jlong JNICALL
70
Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getTotalMemoryFreedImpl(JNIEnv *env, jobject beanInstance, jint id)
71
{
72
return getCollectorField(env, id, FIELD_TOTAL_MEMORY_FREED);
73
}
74
75
jlong JNICALL
76
Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getTotalCompactsImpl(JNIEnv *env, jobject beanInstance, jint id)
77
{
78
return getCollectorField(env, id, FIELD_TOTAL_COMPACTS);
79
}
80
81
jlong JNICALL
82
Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getMemoryUsedImpl(JNIEnv *env, jobject beanInstance, jint id)
83
{
84
return getCollectorField(env, id, FIELD_MEMORY_USED);
85
}
86
87
static UDATA
88
getIndexFromCollectorID(J9JavaLangManagementData *mgmt, UDATA id)
89
{
90
UDATA idx = 0;
91
92
for(; idx < mgmt->supportedCollectors; ++idx) {
93
if ((J9VM_MANAGEMENT_GC_HEAP_ID_MASK & mgmt->garbageCollectors[idx].id) == (J9VM_MANAGEMENT_GC_HEAP_ID_MASK & id)) {
94
break;
95
}
96
}
97
return idx;
98
}
99
100
jobject JNICALL
101
Java_com_ibm_lang_management_internal_ExtendedGarbageCollectorMXBeanImpl_getLastGcInfoImpl(JNIEnv *env, jobject beanInstance, jint id)
102
{
103
J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM;
104
J9JavaLangManagementData *mgmt = javaVM->managementData;
105
J9GarbageCollectorData *gc = &mgmt->garbageCollectors[getIndexFromCollectorID(mgmt, (UDATA) id)];
106
J9GarbageCollectionInfo *gcInfo = &gc->lastGcInfo;
107
jclass gcBean = NULL;
108
jmethodID callBackID = NULL;
109
110
U_32 idx = 0;
111
jlongArray initialArray = NULL;
112
jlongArray preUsedArray = NULL;
113
jlongArray preCommittedArray = NULL;
114
jlongArray preMaxArray = NULL;
115
jlongArray postUsedArray = NULL;
116
jlongArray postCommittedArray = NULL;
117
jlongArray postMaxArray = NULL;
118
119
jlong* initialArrayElems = NULL;
120
jlong* preUsedArrayElems = NULL;
121
jlong* preCommittedArrayElems = NULL;
122
jlong* preMaxArrayElems = NULL;
123
jlong* postUsedArrayElems = NULL;
124
jlong* postCommittedArrayElems = NULL;
125
jlong* postMaxArrayElems = NULL;
126
127
/* collectionCount */
128
if (0 == gc->lastGcInfo.index) {
129
/* return NULL before the first collection */
130
goto fail;
131
}
132
133
gcBean = (*env)->GetObjectClass(env, beanInstance);
134
if (NULL == gcBean) {
135
goto fail;
136
}
137
138
if (!initializeJavaLangStringIDCache(env)) {
139
goto fail;
140
}
141
142
callBackID = JCL_CACHE_GET(env, MID_com_ibm_lang_management_internal_ExtendedGarbageCollectorMXBeanImpl_buildGcInfo);
143
if (NULL == callBackID) {
144
callBackID = (*env)->GetStaticMethodID(env, gcBean, "buildGcInfo", "(JJJ[J[J[J[J[J[J[J)Lcom/sun/management/GcInfo;");
145
if (NULL == callBackID) {
146
goto fail;
147
}
148
JCL_CACHE_SET(env, MID_com_ibm_lang_management_internal_ExtendedGarbageCollectorMXBeanImpl_buildGcInfo, callBackID);
149
}
150
151
initialArray = (*env)->NewLongArray(env, gcInfo->arraySize);
152
if (NULL == initialArray) {
153
goto fail;
154
}
155
preUsedArray = (*env)->NewLongArray(env, gcInfo->arraySize);
156
if (NULL == preUsedArray) {
157
goto fail;
158
}
159
preCommittedArray = (*env)->NewLongArray(env, gcInfo->arraySize);
160
if (NULL == preCommittedArray) {
161
goto fail;
162
}
163
preMaxArray = (*env)->NewLongArray(env, gcInfo->arraySize);
164
if (NULL == preMaxArray) {
165
goto fail;
166
}
167
postUsedArray = (*env)->NewLongArray(env, gcInfo->arraySize);
168
if (NULL == postUsedArray) {
169
goto fail;
170
}
171
postCommittedArray = (*env)->NewLongArray(env, gcInfo->arraySize);
172
if (NULL == postCommittedArray) {
173
goto fail;
174
}
175
postMaxArray = (*env)->NewLongArray(env, gcInfo->arraySize);
176
if (NULL == postMaxArray) {
177
goto fail;
178
}
179
180
{
181
jboolean isCopy = JNI_FALSE;
182
initialArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, initialArray, &isCopy);
183
if (NULL == initialArrayElems) {
184
goto fail2;
185
}
186
preUsedArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, preUsedArray, &isCopy);
187
if (NULL == preUsedArrayElems) {
188
goto fail2;
189
}
190
preCommittedArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, preCommittedArray, &isCopy);
191
if (NULL == preCommittedArrayElems) {
192
goto fail2;
193
}
194
preMaxArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, preMaxArray, &isCopy);
195
if (NULL == preMaxArrayElems) {
196
goto fail2;
197
}
198
postUsedArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, postUsedArray, &isCopy);
199
if (NULL == postUsedArrayElems) {
200
goto fail2;
201
}
202
postCommittedArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, postCommittedArray, &isCopy);
203
if (NULL == postCommittedArrayElems) {
204
goto fail2;
205
}
206
postMaxArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, postMaxArray, &isCopy);
207
if (NULL == postMaxArrayElems) {
208
goto fail2;
209
}
210
omrthread_rwmutex_enter_read(mgmt->managementDataLock);
211
for (idx = 0; idx < gcInfo->arraySize; idx++) {
212
initialArrayElems[idx] = gcInfo->initialSize[idx];
213
preUsedArrayElems[idx] = gcInfo->preUsed[idx];
214
preCommittedArrayElems[idx] = gcInfo->preCommitted[idx];
215
preMaxArrayElems[idx] = gcInfo->preMax[idx];
216
postUsedArrayElems[idx] = gcInfo->postUsed[idx];
217
postCommittedArrayElems[idx] = gcInfo->postCommitted[idx];
218
postMaxArrayElems[idx] = gcInfo->postMax[idx];
219
}
220
omrthread_rwmutex_exit_read(mgmt->managementDataLock);
221
(*env)->ReleasePrimitiveArrayCritical(env, initialArray, initialArrayElems, 0);
222
(*env)->ReleasePrimitiveArrayCritical(env, preUsedArray, preUsedArrayElems, 0);
223
(*env)->ReleasePrimitiveArrayCritical(env, preCommittedArray, preCommittedArrayElems, 0);
224
(*env)->ReleasePrimitiveArrayCritical(env, preMaxArray, preMaxArrayElems, 0);
225
(*env)->ReleasePrimitiveArrayCritical(env, postUsedArray, postUsedArrayElems, 0);
226
(*env)->ReleasePrimitiveArrayCritical(env, postCommittedArray, postCommittedArrayElems, 0);
227
(*env)->ReleasePrimitiveArrayCritical(env, postMaxArray, postMaxArrayElems, 0);
228
}
229
230
return (*env)->CallStaticObjectMethod(env, gcBean, callBackID,
231
(jlong)gcInfo->index, (jlong)gcInfo->startTime, (jlong)gcInfo->endTime,
232
initialArray,
233
preUsedArray,
234
preCommittedArray,
235
preMaxArray,
236
postUsedArray,
237
postCommittedArray,
238
postMaxArray);
239
fail2:
240
if (NULL != initialArrayElems) {
241
(*env)->ReleasePrimitiveArrayCritical(env, initialArray, initialArrayElems, 0);
242
}
243
if (NULL != preUsedArrayElems) {
244
(*env)->ReleasePrimitiveArrayCritical(env, preUsedArray, preUsedArrayElems, 0);
245
}
246
if (NULL != preCommittedArrayElems) {
247
(*env)->ReleasePrimitiveArrayCritical(env, preCommittedArray, preCommittedArrayElems, 0);
248
}
249
if (NULL != preMaxArrayElems) {
250
(*env)->ReleasePrimitiveArrayCritical(env, preMaxArray, preMaxArrayElems, 0);
251
}
252
if (NULL != postUsedArrayElems) {
253
(*env)->ReleasePrimitiveArrayCritical(env, postUsedArray, postUsedArrayElems, 0);
254
}
255
if (NULL != postCommittedArrayElems) {
256
(*env)->ReleasePrimitiveArrayCritical(env, postCommittedArray, postCommittedArrayElems, 0);
257
}
258
if (NULL != postMaxArrayElems) {
259
(*env)->ReleasePrimitiveArrayCritical(env, postMaxArray, postMaxArrayElems, 0);
260
}
261
fail:
262
return NULL;
263
}
264
265
static jlong
266
getCollectorField(JNIEnv *env, jint id, GarbageCollectorField field)
267
{
268
J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM;
269
J9JavaLangManagementData *mgmt = javaVM->managementData;
270
jlong result = 0;
271
J9GarbageCollectorData *gc = &mgmt->garbageCollectors[getIndexFromCollectorID(mgmt, (UDATA) id)];
272
273
omrthread_rwmutex_enter_read(mgmt->managementDataLock);
274
switch (field) {
275
case FIELD_TOTAL_GC_TIME :
276
result = (jlong) gc->totalGCTime;
277
break;
278
case FIELD_LASTGC_START_TIME :
279
/* lastGcInfo.startTime is the start time of last GC since the Java virtual machine was started(ms),
280
* LastCollectionStartTime is the start time of last GC in timestamp(ms)
281
*/
282
result = (jlong) (gc->lastGcInfo.startTime + mgmt->vmStartTime);
283
break;
284
case FIELD_LASTGC_END_TIME :
285
/* lastGcInfo.endTime is the end time of last GC since the Java virtual machine was started(ms),
286
* LastCollectionEndTime is the end time of last GC in timestamp(ms)
287
*/
288
result = (jlong) (gc->lastGcInfo.endTime + mgmt->vmStartTime);
289
break;
290
case FIELD_COLLECTION_COUNT :
291
result = (jlong) gc->lastGcInfo.index;
292
break;
293
case FIELD_MEMORY_USED :
294
result = (jlong) gc->memoryUsed;
295
break;
296
case FIELD_TOTAL_MEMORY_FREED :
297
result = (jlong) gc->totalMemoryFreed;
298
break;
299
case FIELD_TOTAL_COMPACTS :
300
result = (jlong) gc->totalCompacts;
301
break;
302
default:
303
break;
304
}
305
omrthread_rwmutex_exit_read(mgmt->managementDataLock);
306
307
return result;
308
}
309
310