Skip to content

Commit

Permalink
Merge pull request #2993 from LinHu2016/issue2982
Browse files Browse the repository at this point in the history
Fix issue relate with CollectionUsageThreshold of memory pool
  • Loading branch information
DanHeidinga committed Oct 16, 2018
2 parents b5547a8 + 85f9c3b commit 1e9f12d
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 26 deletions.
4 changes: 4 additions & 0 deletions runtime/gc_base/modronapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,10 @@ j9gc_is_managedpool_by_collector(J9JavaVM *javaVM, UDATA gcID, UDATA poolID)
{
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);
if (extensions->_HeapManagementMXBeanBackCompatibilityEnabled) {
if (J9_GC_MANAGEMENT_COLLECTOR_SCAVENGE == gcID) {
/* for BackCompatible mode scavenge does not try to reclaim memory from the whole heap, so we do not mark JavaHeap managed by scavenge */
return 0;
}
return 1;
}
UDATA managedPools = 0;
Expand Down
57 changes: 37 additions & 20 deletions runtime/jcl/common/mgmtinit.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1998, 2017 IBM Corp. and others
* Copyright (c) 1998, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -479,6 +479,7 @@ gcStartEvent(J9JavaVM *vm, UDATA heapSize, UDATA heapUsed, UDATA *totals, UDATA
J9MemoryPoolData *memoryPools = mgmt->memoryPools;
J9MemoryNotification *notification = NULL;
J9MemoryNotification *last = NULL;
J9GarbageCollectionInfo* gcInfo = NULL;

UDATA total = 0;
UDATA used = 0;
Expand All @@ -500,21 +501,26 @@ gcStartEvent(J9JavaVM *vm, UDATA heapSize, UDATA heapUsed, UDATA *totals, UDATA

mgmt->preCollectionHeapSize = heapSize;
mgmt->preCollectionHeapUsed = heapUsed;
gcInfo = &gcData->lastGcInfo;

for (idx = 0; idx < mgmt->supportedMemoryPools; ++idx) {
J9MemoryPoolData *memoryPool = &memoryPools[idx];
total = totals[idx];
used = totals[idx] - frees[idx];

memoryPool->preCollectionSize = total;
memoryPool->preCollectionUsed = used;
memoryPool->preCollectionMaxSize = memoryPool->postCollectionMaxSize;
/* update pre Memory Usage of last GcInfo for the collector */
gcInfo->preUsed[idx] = used;
gcInfo->preCommitted[idx] = total;
if (0 == gcInfo->postMax[idx]) {
gcInfo->postMax[idx] = memoryPool->postCollectionMaxSize;
}
gcInfo->preMax[idx] = gcInfo->postMax[idx];

/* check the peak usage and update */
if (memoryPool->peakUsed < used) {
memoryPool->peakUsed = used;
memoryPool->peakSize = total;
memoryPool->peakMax = memoryPool->preCollectionMaxSize;
memoryPool->peakMax = gcInfo->preMax[idx];
}

/* if a heap usage threshold is set, check whether we are above or below */
Expand Down Expand Up @@ -546,7 +552,7 @@ gcStartEvent(J9JavaVM *vm, UDATA heapSize, UDATA heapUsed, UDATA *totals, UDATA
notification->usageThreshold->poolID = memoryPool->id;
notification->usageThreshold->usedSize = used;
notification->usageThreshold->totalSize = total;
notification->usageThreshold->maxSize = memoryPool->preCollectionMaxSize;
notification->usageThreshold->maxSize = gcInfo->preMax[idx];
notification->usageThreshold->thresholdCrossingCount = memoryPool->usageThresholdCrossedCount;
notification->sequenceNumber = mgmt->notificationCount++;

Expand Down Expand Up @@ -601,6 +607,7 @@ gcEndEvent(J9JavaVM *vm, UDATA heapSize, UDATA heapUsed, UDATA *totals, UDATA *f

UDATA total = 0;
UDATA used = 0;
UDATA max = 0;
UDATA idx = 0;
U_32 notificationEnabled = 0;

Expand All @@ -613,27 +620,31 @@ gcEndEvent(J9JavaVM *vm, UDATA heapSize, UDATA heapUsed, UDATA *totals, UDATA *f
/* lock the management struct */
omrthread_rwmutex_enter_write(mgmt->managementDataLock);

mgmt->lastGCID = (U_32)collectorID;
mgmt->postCollectionHeapSize = heapSize;
mgmt->postCollectionHeapUsed = heapUsed;
gcInfo = &gcData->lastGcInfo;

for (idx = 0; idx < mgmt->supportedMemoryPools; ++idx) {
J9MemoryPoolData *memoryPool = &memoryPools[idx];
total = totals[idx];
used = totals[idx] - frees[idx];
max = maxs[idx];

memoryPool->postCollectionSize = total;
memoryPool->postCollectionUsed = used;
memoryPool->postCollectionMaxSize = maxs[idx];
/* update post Memory Usage of last GcInfo for the collector */
gcInfo->postUsed[idx] = used;
gcInfo->postCommitted[idx] = total;
gcInfo->postMax[idx] = max;

/* check the peak usage and update */
if (memoryPool->peakUsed < used) {
memoryPool->peakUsed = used;
memoryPool->peakSize = total;
memoryPool->peakMax = memoryPool->postCollectionMaxSize;
memoryPool->peakMax = max;
}

/* if a heap collection threshold is set, check whether we are above or below */
if (0 < memoryPool->collectionUsageThreshold) {
/* if a memory pool collection threshold is set and the memory pool is managed by the collector, check whether we are above or below */
if ((0 < memoryPool->collectionUsageThreshold) && mmFuncs->j9gc_is_managedpool_by_collector(vm, (UDATA)(gcData->id & J9VM_MANAGEMENT_GC_HEAP_ID_MASK), (UDATA)(memoryPool->id & J9VM_MANAGEMENT_POOL_HEAP_ID_MASK))) {
if (memoryPool->collectionUsageThreshold < used) {
/* usage above threshold now, was it below threshold last time? */
if (0 == (memoryPool->notificationState & COLLECTION_THRESHOLD_EXCEEDED)) {
Expand Down Expand Up @@ -661,7 +672,7 @@ gcEndEvent(J9JavaVM *vm, UDATA heapSize, UDATA heapUsed, UDATA *totals, UDATA *f
notification->usageThreshold->poolID = memoryPool->id;
notification->usageThreshold->usedSize = used;
notification->usageThreshold->totalSize = total;
notification->usageThreshold->maxSize = memoryPool->postCollectionMaxSize;
notification->usageThreshold->maxSize = max;
notification->usageThreshold->thresholdCrossingCount = memoryPool->collectionUsageThresholdCrossedCount;
notification->sequenceNumber = mgmt->notificationCount++;

Expand Down Expand Up @@ -731,7 +742,6 @@ gcEndEvent(J9JavaVM *vm, UDATA heapSize, UDATA heapUsed, UDATA *totals, UDATA *f
/* update nonHeap memory pools for postCollection */
updateNonHeapMemoryPoolSizes(vm, mgmt, TRUE);
/* update J9GarbageCollectionInfo for the collector */
gcInfo = &gcData->lastGcInfo;

gcInfo->gcID = gcData->id;
gcInfo->gcAction = mmFuncs->j9gc_get_gc_action(vm, (gcInfo->gcID & J9VM_MANAGEMENT_GC_HEAP_ID_MASK));
Expand All @@ -741,12 +751,19 @@ gcEndEvent(J9JavaVM *vm, UDATA heapSize, UDATA heapUsed, UDATA *totals, UDATA *f
for (idx = 0; supportedMemoryPools > idx; ++idx) {
J9MemoryPoolData *memoryPool = &memoryPools[idx];
gcInfo->initialSize[idx] = memoryPool->initialSize;
gcInfo->preUsed[idx] = memoryPool->preCollectionUsed;
gcInfo->preCommitted[idx] = memoryPool->preCollectionSize;
gcInfo->preMax[idx] = (I_64) memoryPool->preCollectionMaxSize;
gcInfo->postUsed[idx] = memoryPool->postCollectionUsed;
gcInfo->postCommitted[idx] = memoryPool->postCollectionSize;
gcInfo->postMax[idx] = (I_64) memoryPool->postCollectionMaxSize;
if (mmFuncs->j9gc_is_managedpool_by_collector(vm, (UDATA)(gcData->id & J9VM_MANAGEMENT_GC_HEAP_ID_MASK), (UDATA)(memoryPool->id & J9VM_MANAGEMENT_POOL_HEAP_ID_MASK))) {
/**
* the memoryPool is managed by this collection, update preCollection postCollection Memory Usage of this memory Pool
* gcInfo keep memory Usage before and after this gc
* preCollection postCollection Memory Usage in memoryPool only keep information for the GC, which recycle the memory pool
*/
memoryPool->preCollectionUsed = gcInfo->preUsed[idx];
memoryPool->preCollectionSize = gcInfo->preCommitted[idx];
memoryPool->preCollectionMaxSize = (U_64)gcInfo->preMax[idx];
memoryPool->postCollectionUsed = gcInfo->postUsed[idx];
memoryPool->postCollectionSize = gcInfo->postCommitted[idx];
memoryPool->postCollectionMaxSize = (U_64)gcInfo->postMax[idx];
}
}
/* non heap memory pools */
for (; supportedMemoryPools + supportedNonHeapMemoryPools > idx; ++idx) {
Expand Down
44 changes: 38 additions & 6 deletions runtime/jcl/common/mgmtmempool.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1998, 2016 IBM Corp. and others
* Copyright (c) 1998, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -27,6 +27,7 @@

static jobject processSegmentList(JNIEnv *env, jclass memoryUsage, jobject memUsageConstructor, J9MemorySegmentList *segList, U_64 initSize, U_64 *storedPeakSize, U_64 *storedPeakUsed, UDATA action);
static UDATA getIndexFromPoolID(J9JavaLangManagementData *mgmt, UDATA id);
static UDATA getIndexFromCollectorID(J9JavaLangManagementData *mgmt, UDATA id);
static J9MemorySegmentList *getMemorySegmentList(J9JavaVM *javaVM, jint id);

jobject JNICALL
Expand Down Expand Up @@ -129,7 +130,13 @@ Java_com_ibm_java_lang_management_internal_MemoryPoolMXBeanImpl_getPeakUsageImpl
if (currentUsed > pool->peakUsed) {
pool->peakUsed = currentUsed;
pool->peakSize = currentCommitted;
pool->peakMax = pool->postCollectionMaxSize;
if (0 != mgmt->lastGCID) {
J9GarbageCollectorData *gcData = &mgmt->garbageCollectors[getIndexFromCollectorID(mgmt, mgmt->lastGCID)];
J9GarbageCollectionInfo* gcInfo = &gcData->lastGcInfo;
pool->peakMax = gcInfo->postMax[idx];
} else {
pool->peakMax = pool->postCollectionMaxSize;
}
used = currentUsed;
committed = currentCommitted;
max = pool->peakMax;
Expand Down Expand Up @@ -180,7 +187,14 @@ Java_com_ibm_java_lang_management_internal_MemoryPoolMXBeanImpl_getUsageImpl(JNI
omrthread_rwmutex_enter_read(mgmt->managementDataLock);
peak = (jlong) pool->peakUsed;
init = (jlong) pool->initialSize;
max = (jlong) pool->postCollectionMaxSize;
if (0 != mgmt->lastGCID) {
J9GarbageCollectorData *gcData = &mgmt->garbageCollectors[getIndexFromCollectorID(mgmt, mgmt->lastGCID)];
J9GarbageCollectionInfo* gcInfo = &gcData->lastGcInfo;
max = (jlong) gcInfo->postMax[idx];
} else {
max = (jlong) pool->postCollectionMaxSize;
}

omrthread_rwmutex_exit_read(mgmt->managementDataLock);

if (used > peak) {
Expand All @@ -189,7 +203,7 @@ Java_com_ibm_java_lang_management_internal_MemoryPoolMXBeanImpl_getUsageImpl(JNI
if ((U_64)used > pool->peakUsed) {
pool->peakUsed = used;
pool->peakSize = committed;
pool->peakMax = pool->postCollectionMaxSize;
pool->peakMax = max;
}
omrthread_rwmutex_exit_write(mgmt->managementDataLock);
}
Expand Down Expand Up @@ -352,7 +366,13 @@ Java_com_ibm_java_lang_management_internal_MemoryPoolMXBeanImpl_resetPeakUsageIm
omrthread_rwmutex_enter_write(mgmt->managementDataLock);
pool->peakUsed = used;
pool->peakSize = committed;
pool->peakMax = pool->postCollectionMaxSize;
if (0 != mgmt->lastGCID) {
J9GarbageCollectorData *gcData = &mgmt->garbageCollectors[getIndexFromCollectorID(mgmt, mgmt->lastGCID)];
J9GarbageCollectionInfo* gcInfo = &gcData->lastGcInfo;
pool->peakMax = gcInfo->postMax[idx];
} else {
pool->peakMax = pool->postCollectionMaxSize;
}
omrthread_rwmutex_exit_write(mgmt->managementDataLock);
} else {
/* NonHeap MemoryPool */
Expand Down Expand Up @@ -496,14 +516,26 @@ static UDATA
getIndexFromPoolID(J9JavaLangManagementData *mgmt, UDATA id)
{
UDATA idx = 0;
for(; idx < mgmt->supportedMemoryPools; idx++) {
for (idx = 0; idx < mgmt->supportedMemoryPools; idx++) {
if ((mgmt->memoryPools[idx].id & J9VM_MANAGEMENT_POOL_HEAP_ID_MASK) == (id & J9VM_MANAGEMENT_POOL_HEAP_ID_MASK)) {
break;
}
}
return idx;
}

static UDATA
getIndexFromCollectorID(J9JavaLangManagementData *mgmt, UDATA id)
{
UDATA idx = 0;
for (idx = 0; idx < mgmt->supportedCollectors; ++idx) {
if ((J9VM_MANAGEMENT_GC_HEAP_ID_MASK & mgmt->garbageCollectors[idx].id) == (J9VM_MANAGEMENT_GC_HEAP_ID_MASK & id)) {
break;
}
}
return idx;
}

static J9MemorySegmentList *
getMemorySegmentList(J9JavaVM *javaVM, jint id)
{
Expand Down
1 change: 1 addition & 0 deletions runtime/oti/j9nonbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,7 @@ typedef struct J9JavaLangManagementData {
U_32 supportedMemoryPools;
U_32 supportedNonHeapMemoryPools;
U_32 supportedCollectors;
U_32 lastGCID;
struct J9MemoryPoolData *memoryPools;
struct J9NonHeapMemoryData *nonHeapMemoryPools;
struct J9GarbageCollectorData *garbageCollectors;
Expand Down

0 comments on commit 1e9f12d

Please sign in to comment.