Path: blob/master/runtime/jcl/common/mgmtgc.c
12872 views
/*******************************************************************************1* Copyright (c) 1998, 2018 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* 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-exception20*******************************************************************************/2122#include "jni.h"23#include "j9.h"24#include "jclglob.h"25#include "jclprots.h"26#include "mgmtinit.h"27#include "jniidcacheinit.h"2829typedef enum {30FIELD_TOTAL_GC_TIME,31FIELD_LASTGC_START_TIME,32FIELD_LASTGC_END_TIME,33FIELD_COLLECTION_COUNT,34FIELD_MEMORY_USED,35FIELD_TOTAL_MEMORY_FREED,36FIELD_TOTAL_COMPACTS37} GarbageCollectorField;3839#define GC_FIELD_TOTAL_GC_TIME4041static UDATA getIndexFromCollectorID(J9JavaLangManagementData *mgmt, UDATA id);42static jlong getCollectorField(JNIEnv *env, jint id, GarbageCollectorField field);4344jlong JNICALL45Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getCollectionCountImpl(JNIEnv *env, jobject beanInstance, jint id)46{47return getCollectorField(env, id, FIELD_COLLECTION_COUNT);48}4950jlong JNICALL51Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getCollectionTimeImpl(JNIEnv *env, jobject beanInstance, jint id)52{53return getCollectorField(env, id, FIELD_TOTAL_GC_TIME);54}5556jlong JNICALL57Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getLastCollectionStartTimeImpl(JNIEnv *env, jobject beanInstance, jint id)58{59return getCollectorField(env, id, FIELD_LASTGC_START_TIME);60}6162jlong JNICALL63Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getLastCollectionEndTimeImpl(JNIEnv *env, jobject beanInstance, jint id)64{65return getCollectorField(env, id, FIELD_LASTGC_END_TIME);66}6768jlong JNICALL69Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getTotalMemoryFreedImpl(JNIEnv *env, jobject beanInstance, jint id)70{71return getCollectorField(env, id, FIELD_TOTAL_MEMORY_FREED);72}7374jlong JNICALL75Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getTotalCompactsImpl(JNIEnv *env, jobject beanInstance, jint id)76{77return getCollectorField(env, id, FIELD_TOTAL_COMPACTS);78}7980jlong JNICALL81Java_com_ibm_java_lang_management_internal_GarbageCollectorMXBeanImpl_getMemoryUsedImpl(JNIEnv *env, jobject beanInstance, jint id)82{83return getCollectorField(env, id, FIELD_MEMORY_USED);84}8586static UDATA87getIndexFromCollectorID(J9JavaLangManagementData *mgmt, UDATA id)88{89UDATA idx = 0;9091for(; idx < mgmt->supportedCollectors; ++idx) {92if ((J9VM_MANAGEMENT_GC_HEAP_ID_MASK & mgmt->garbageCollectors[idx].id) == (J9VM_MANAGEMENT_GC_HEAP_ID_MASK & id)) {93break;94}95}96return idx;97}9899jobject JNICALL100Java_com_ibm_lang_management_internal_ExtendedGarbageCollectorMXBeanImpl_getLastGcInfoImpl(JNIEnv *env, jobject beanInstance, jint id)101{102J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM;103J9JavaLangManagementData *mgmt = javaVM->managementData;104J9GarbageCollectorData *gc = &mgmt->garbageCollectors[getIndexFromCollectorID(mgmt, (UDATA) id)];105J9GarbageCollectionInfo *gcInfo = &gc->lastGcInfo;106jclass gcBean = NULL;107jmethodID callBackID = NULL;108109U_32 idx = 0;110jlongArray initialArray = NULL;111jlongArray preUsedArray = NULL;112jlongArray preCommittedArray = NULL;113jlongArray preMaxArray = NULL;114jlongArray postUsedArray = NULL;115jlongArray postCommittedArray = NULL;116jlongArray postMaxArray = NULL;117118jlong* initialArrayElems = NULL;119jlong* preUsedArrayElems = NULL;120jlong* preCommittedArrayElems = NULL;121jlong* preMaxArrayElems = NULL;122jlong* postUsedArrayElems = NULL;123jlong* postCommittedArrayElems = NULL;124jlong* postMaxArrayElems = NULL;125126/* collectionCount */127if (0 == gc->lastGcInfo.index) {128/* return NULL before the first collection */129goto fail;130}131132gcBean = (*env)->GetObjectClass(env, beanInstance);133if (NULL == gcBean) {134goto fail;135}136137if (!initializeJavaLangStringIDCache(env)) {138goto fail;139}140141callBackID = JCL_CACHE_GET(env, MID_com_ibm_lang_management_internal_ExtendedGarbageCollectorMXBeanImpl_buildGcInfo);142if (NULL == callBackID) {143callBackID = (*env)->GetStaticMethodID(env, gcBean, "buildGcInfo", "(JJJ[J[J[J[J[J[J[J)Lcom/sun/management/GcInfo;");144if (NULL == callBackID) {145goto fail;146}147JCL_CACHE_SET(env, MID_com_ibm_lang_management_internal_ExtendedGarbageCollectorMXBeanImpl_buildGcInfo, callBackID);148}149150initialArray = (*env)->NewLongArray(env, gcInfo->arraySize);151if (NULL == initialArray) {152goto fail;153}154preUsedArray = (*env)->NewLongArray(env, gcInfo->arraySize);155if (NULL == preUsedArray) {156goto fail;157}158preCommittedArray = (*env)->NewLongArray(env, gcInfo->arraySize);159if (NULL == preCommittedArray) {160goto fail;161}162preMaxArray = (*env)->NewLongArray(env, gcInfo->arraySize);163if (NULL == preMaxArray) {164goto fail;165}166postUsedArray = (*env)->NewLongArray(env, gcInfo->arraySize);167if (NULL == postUsedArray) {168goto fail;169}170postCommittedArray = (*env)->NewLongArray(env, gcInfo->arraySize);171if (NULL == postCommittedArray) {172goto fail;173}174postMaxArray = (*env)->NewLongArray(env, gcInfo->arraySize);175if (NULL == postMaxArray) {176goto fail;177}178179{180jboolean isCopy = JNI_FALSE;181initialArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, initialArray, &isCopy);182if (NULL == initialArrayElems) {183goto fail2;184}185preUsedArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, preUsedArray, &isCopy);186if (NULL == preUsedArrayElems) {187goto fail2;188}189preCommittedArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, preCommittedArray, &isCopy);190if (NULL == preCommittedArrayElems) {191goto fail2;192}193preMaxArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, preMaxArray, &isCopy);194if (NULL == preMaxArrayElems) {195goto fail2;196}197postUsedArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, postUsedArray, &isCopy);198if (NULL == postUsedArrayElems) {199goto fail2;200}201postCommittedArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, postCommittedArray, &isCopy);202if (NULL == postCommittedArrayElems) {203goto fail2;204}205postMaxArrayElems = (jlong*) (*env)->GetPrimitiveArrayCritical(env, postMaxArray, &isCopy);206if (NULL == postMaxArrayElems) {207goto fail2;208}209omrthread_rwmutex_enter_read(mgmt->managementDataLock);210for (idx = 0; idx < gcInfo->arraySize; idx++) {211initialArrayElems[idx] = gcInfo->initialSize[idx];212preUsedArrayElems[idx] = gcInfo->preUsed[idx];213preCommittedArrayElems[idx] = gcInfo->preCommitted[idx];214preMaxArrayElems[idx] = gcInfo->preMax[idx];215postUsedArrayElems[idx] = gcInfo->postUsed[idx];216postCommittedArrayElems[idx] = gcInfo->postCommitted[idx];217postMaxArrayElems[idx] = gcInfo->postMax[idx];218}219omrthread_rwmutex_exit_read(mgmt->managementDataLock);220(*env)->ReleasePrimitiveArrayCritical(env, initialArray, initialArrayElems, 0);221(*env)->ReleasePrimitiveArrayCritical(env, preUsedArray, preUsedArrayElems, 0);222(*env)->ReleasePrimitiveArrayCritical(env, preCommittedArray, preCommittedArrayElems, 0);223(*env)->ReleasePrimitiveArrayCritical(env, preMaxArray, preMaxArrayElems, 0);224(*env)->ReleasePrimitiveArrayCritical(env, postUsedArray, postUsedArrayElems, 0);225(*env)->ReleasePrimitiveArrayCritical(env, postCommittedArray, postCommittedArrayElems, 0);226(*env)->ReleasePrimitiveArrayCritical(env, postMaxArray, postMaxArrayElems, 0);227}228229return (*env)->CallStaticObjectMethod(env, gcBean, callBackID,230(jlong)gcInfo->index, (jlong)gcInfo->startTime, (jlong)gcInfo->endTime,231initialArray,232preUsedArray,233preCommittedArray,234preMaxArray,235postUsedArray,236postCommittedArray,237postMaxArray);238fail2:239if (NULL != initialArrayElems) {240(*env)->ReleasePrimitiveArrayCritical(env, initialArray, initialArrayElems, 0);241}242if (NULL != preUsedArrayElems) {243(*env)->ReleasePrimitiveArrayCritical(env, preUsedArray, preUsedArrayElems, 0);244}245if (NULL != preCommittedArrayElems) {246(*env)->ReleasePrimitiveArrayCritical(env, preCommittedArray, preCommittedArrayElems, 0);247}248if (NULL != preMaxArrayElems) {249(*env)->ReleasePrimitiveArrayCritical(env, preMaxArray, preMaxArrayElems, 0);250}251if (NULL != postUsedArrayElems) {252(*env)->ReleasePrimitiveArrayCritical(env, postUsedArray, postUsedArrayElems, 0);253}254if (NULL != postCommittedArrayElems) {255(*env)->ReleasePrimitiveArrayCritical(env, postCommittedArray, postCommittedArrayElems, 0);256}257if (NULL != postMaxArrayElems) {258(*env)->ReleasePrimitiveArrayCritical(env, postMaxArray, postMaxArrayElems, 0);259}260fail:261return NULL;262}263264static jlong265getCollectorField(JNIEnv *env, jint id, GarbageCollectorField field)266{267J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM;268J9JavaLangManagementData *mgmt = javaVM->managementData;269jlong result = 0;270J9GarbageCollectorData *gc = &mgmt->garbageCollectors[getIndexFromCollectorID(mgmt, (UDATA) id)];271272omrthread_rwmutex_enter_read(mgmt->managementDataLock);273switch (field) {274case FIELD_TOTAL_GC_TIME :275result = (jlong) gc->totalGCTime;276break;277case FIELD_LASTGC_START_TIME :278/* lastGcInfo.startTime is the start time of last GC since the Java virtual machine was started(ms),279* LastCollectionStartTime is the start time of last GC in timestamp(ms)280*/281result = (jlong) (gc->lastGcInfo.startTime + mgmt->vmStartTime);282break;283case FIELD_LASTGC_END_TIME :284/* lastGcInfo.endTime is the end time of last GC since the Java virtual machine was started(ms),285* LastCollectionEndTime is the end time of last GC in timestamp(ms)286*/287result = (jlong) (gc->lastGcInfo.endTime + mgmt->vmStartTime);288break;289case FIELD_COLLECTION_COUNT :290result = (jlong) gc->lastGcInfo.index;291break;292case FIELD_MEMORY_USED :293result = (jlong) gc->memoryUsed;294break;295case FIELD_TOTAL_MEMORY_FREED :296result = (jlong) gc->totalMemoryFreed;297break;298case FIELD_TOTAL_COMPACTS :299result = (jlong) gc->totalCompacts;300break;301default:302break;303}304omrthread_rwmutex_exit_read(mgmt->managementDataLock);305306return result;307}308309310