Path: blob/master/runtime/gc_base/QueryGCStatus.cpp
5986 views
1/*******************************************************************************2* Copyright (c) 1991, 2014 IBM Corp. and others3*4* This program and the accompanying materials are made available under5* the terms of the Eclipse Public License 2.0 which accompanies this6* 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 and8* is available at https://www.apache.org/licenses/LICENSE-2.0.9*10* This Source Code may also be made available under the following11* Secondary Licenses when the conditions for such availability set12* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU13* General Public License, version 2 with the GNU Classpath14* Exception [1] and GNU General Public License, version 2 with the15* OpenJDK Assembly Exception [2].16*17* [1] https://www.gnu.org/software/classpath/license.html18* [2] http://openjdk.java.net/legal/assembly-exception.html19*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-exception21*******************************************************************************/2223#include "j9.h"24#include "j9cfg.h"25#include "jni.h"26#include "j9protos.h"2728#include "AllocationFailureStats.hpp"29#include "GCExtensions.hpp"30#include "Heap.hpp"31#include "MemorySpace.hpp"32#include "MemorySubSpace.hpp"33#include "VMInterface.hpp"3435extern "C" {36#define QUERY_GC_STATUS_NUMBER_OF_HEAPS_SCAVENGER_ENABLED 237#define QUERY_GC_STATUS_NUMBER_OF_HEAPS_SCAVENGER_DISABLED 138/**39* Query the state of the Garbage Collector.40*41* Initially, the API should be called with a statusSize of 0. This call will return42* JNI_EINVAL and nHeaps, which is the number of storage structures for which data will be43* returned. This allows the caller to calculate how large statusSize should be by using44* something similar to nHeaps * sizeof(GCStatus).45*46* The API returns the data in the supplied array and can be interrogated using the heap field47* to identify whether the data is for a heap or shared memory. If the data is for shared memory,48* the count field can be used to identify whether the data is for the shared memory page pool49* or for a subpool. There is no implied order in which the data is returned.50*51* @param vm The javaVM52* @param nHeap Number of heaps for which data has been returned53* @param status An array of GCStatus structures54* @param statusSize The size of the status array in bytes55*56* @return JNI_OK Call completed successfully57* @return JNI_ERR Processing the request failed58* @return JNI_EINVAL The query given was invalid, for example, the size of the status array is too small.59*/60jint JNICALL61queryGCStatus(JavaVM *vm, jint *nHeaps, GCStatus *status, jint statusSize)62{63J9JavaVM *javaVM = (J9JavaVM *)vm;64jint filledElements = *nHeaps; /* Number of elements of status that are filled */65jint returnCode = JNI_OK;6667/* may not be attached to a VM */68/*69if (omrthread_attach_ex(NULL, J9THREAD_ATTR_DEFAULT)) {70return JNI_ERR;71}72javaVM->internalVMFunctions->acquireExclusiveVMAccessFromExternalThread(javaVM);73*/7475/* From here on in, must branch to exit to return. Do not return directly */76MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);77MM_MemorySpace *memorySpace = extensions->heap->getMemorySpaceList();7879/* first call? */80if (0 == statusSize) {81/* Return JNI_EINVAL and update nHeaps to be the number of storage structures82* that will be populated.83*/84*nHeaps = 0;85while (memorySpace) {86#if defined (J9VM_GC_MODRON_SCAVENGER)87if (extensions->scavengerEnabled) {88*nHeaps += QUERY_GC_STATUS_NUMBER_OF_HEAPS_SCAVENGER_ENABLED;89} else90#endif /* J9VM_GC_MODRON_SCAVENGER */91{92*nHeaps += QUERY_GC_STATUS_NUMBER_OF_HEAPS_SCAVENGER_DISABLED;93}9495memorySpace = memorySpace->getNext();96}97returnCode = JNI_EINVAL;98goto done;99}100101/* Sanity check, it may be some incorrect large number, but it can never be negative */102if (*nHeaps < 0) {103returnCode = JNI_EINVAL;104goto done;105}106107/* Sanity check, it may be some incorrect large number, but it can never be negative */108if (statusSize < 0) {109returnCode = JNI_EINVAL;110goto done;111}112113/* Sanity check, are there enough array elements to hold the requested data? */114if (statusSize != (*nHeaps) * (jint)sizeof(GCStatus)) {115returnCode = JNI_EINVAL;116goto done;117}118119/* Initialize the return structure to known values */120memset((void *)status, 0, statusSize);121while ((NULL != memorySpace) && (0 != filledElements)) {122#if defined(J9VM_GC_MODRON_SCAVENGER)123if (extensions->scavengerEnabled) {124MM_MemorySubSpace *defaultMemorySubSpace = memorySpace->getDefaultMemorySubSpace();125MM_AllocationFailureStats *allocationFailureStats = defaultMemorySubSpace->getAllocationFailureStats();126status->heap = (jint) JNI_GCQUERY_NURSERY_HEAP;127status->count = (jint) allocationFailureStats->allocationFailureCount;128status->freestorage = (jlong) defaultMemorySubSpace->getActualFreeMemorySize();129status->totalstorage = (jlong) defaultMemorySubSpace->getActiveMemorySize();130status += 1;131filledElements -=1;132}133#endif /* J9VM_GC_MODRON_SCAVENGER */134135MM_MemorySubSpace *tenuredMemorySubSpace = memorySpace->getTenureMemorySubSpace();136MM_AllocationFailureStats *tenuredAllocationFailureStats = tenuredMemorySubSpace->getAllocationFailureStats();137status->heap = (jint) JNI_GCQUERY_MATURE_HEAP;138status->count = (jint) tenuredAllocationFailureStats->allocationFailureCount;139status->freestorage = (jlong) tenuredMemorySubSpace->getActualFreeMemorySize();140status->totalstorage = (jlong) tenuredMemorySubSpace->getActiveMemorySize();141status += 1;142filledElements -=1;143144memorySpace = memorySpace->getNext();145}146147/* Yet another sanity check. If there is a mismatch between the expected number148* of elements to be returned, and the actual number of elements filled149* inform the user. Don't wipe the data already collected.150*/151if ((NULL != memorySpace) || (0 != filledElements)) {152returnCode = JNI_EINVAL;153}154155done:156157/*158javaVM->internalVMFunctions->releaseExclusiveVMAccessFromExternalThread(javaVM);159omrthread_detach(NULL);160*/161return returnCode;162}163164} /* extern "C" */165166167168