8195115: G1 Old Gen MemoryPool CollectionUsage.used values don't reflect mixed GC results
Memory pools can now be optional collection participants, e.g., G1 Old Gen in an incremental collection. Reviewed-by: ehelin, mchung
This commit is contained in:
parent
425e1a8bb8
commit
ebe240f3f4
@ -8088,6 +8088,7 @@ TraceCMSMemoryManagerStats::TraceCMSMemoryManagerStats(CMSCollector::CollectorSt
|
||||
case CMSCollector::InitialMarking:
|
||||
initialize(manager /* GC manager */ ,
|
||||
cause /* cause of the GC */,
|
||||
true /* allMemoryPoolsAffected */,
|
||||
true /* recordGCBeginTime */,
|
||||
true /* recordPreGCUsage */,
|
||||
false /* recordPeakUsage */,
|
||||
@ -8100,6 +8101,7 @@ TraceCMSMemoryManagerStats::TraceCMSMemoryManagerStats(CMSCollector::CollectorSt
|
||||
case CMSCollector::FinalMarking:
|
||||
initialize(manager /* GC manager */ ,
|
||||
cause /* cause of the GC */,
|
||||
true /* allMemoryPoolsAffected */,
|
||||
false /* recordGCBeginTime */,
|
||||
false /* recordPreGCUsage */,
|
||||
false /* recordPeakUsage */,
|
||||
@ -8112,6 +8114,7 @@ TraceCMSMemoryManagerStats::TraceCMSMemoryManagerStats(CMSCollector::CollectorSt
|
||||
case CMSCollector::Sweeping:
|
||||
initialize(manager /* GC manager */ ,
|
||||
cause /* cause of the GC */,
|
||||
true /* allMemoryPoolsAffected */,
|
||||
false /* recordGCBeginTime */,
|
||||
false /* recordPreGCUsage */,
|
||||
true /* recordPeakUsage */,
|
||||
|
@ -1737,7 +1737,7 @@ void G1CollectedHeap::initialize_serviceability() {
|
||||
|
||||
_memory_manager.add_pool(_eden_pool);
|
||||
_memory_manager.add_pool(_survivor_pool);
|
||||
|
||||
_memory_manager.add_pool(_old_pool, false /* always_affected_by_gc */);
|
||||
}
|
||||
|
||||
void G1CollectedHeap::stop() {
|
||||
@ -2833,7 +2833,8 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
|
||||
log_info(gc,task)("Using %u workers of %u for evacuation", active_workers, workers()->total_workers());
|
||||
|
||||
TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
|
||||
TraceMemoryManagerStats tms(&_memory_manager, gc_cause());
|
||||
TraceMemoryManagerStats tms(&_memory_manager, gc_cause(),
|
||||
collector_state()->yc_type() == Mixed /* allMemoryPoolsAffected */);
|
||||
|
||||
G1HeapTransition heap_transition(this);
|
||||
size_t heap_used_bytes_before_gc = used();
|
||||
|
@ -43,13 +43,15 @@ MemoryManager::MemoryManager(const char* name) : _name(name) {
|
||||
(void)const_cast<instanceOop&>(_memory_mgr_obj = instanceOop(NULL));
|
||||
}
|
||||
|
||||
void MemoryManager::add_pool(MemoryPool* pool) {
|
||||
assert(_num_pools < MemoryManager::max_num_pools, "_num_pools exceeds the max");
|
||||
if (_num_pools < MemoryManager::max_num_pools) {
|
||||
_pools[_num_pools] = pool;
|
||||
int MemoryManager::add_pool(MemoryPool* pool) {
|
||||
int index = _num_pools;
|
||||
assert(index < MemoryManager::max_num_pools, "_num_pools exceeds the max");
|
||||
if (index < MemoryManager::max_num_pools) {
|
||||
_pools[index] = pool;
|
||||
_num_pools++;
|
||||
}
|
||||
pool->add_manager(this);
|
||||
return index;
|
||||
}
|
||||
|
||||
MemoryManager* MemoryManager::get_code_cache_memory_manager() {
|
||||
@ -189,6 +191,15 @@ GCMemoryManager::~GCMemoryManager() {
|
||||
delete _current_gc_stat;
|
||||
}
|
||||
|
||||
void GCMemoryManager::add_pool(MemoryPool* pool) {
|
||||
add_pool(pool, true);
|
||||
}
|
||||
|
||||
void GCMemoryManager::add_pool(MemoryPool* pool, bool always_affected_by_gc) {
|
||||
int index = MemoryManager::add_pool(pool);
|
||||
_pool_always_affected_by_gc[index] = always_affected_by_gc;
|
||||
}
|
||||
|
||||
void GCMemoryManager::initialize_gc_stat_info() {
|
||||
assert(MemoryService::num_memory_pools() > 0, "should have one or more memory pools");
|
||||
_last_gc_stat = new(ResourceObj::C_HEAP, mtGC) GCStatInfo(MemoryService::num_memory_pools());
|
||||
@ -230,7 +241,8 @@ void GCMemoryManager::gc_begin(bool recordGCBeginTime, bool recordPreGCUsage,
|
||||
void GCMemoryManager::gc_end(bool recordPostGCUsage,
|
||||
bool recordAccumulatedGCTime,
|
||||
bool recordGCEndTime, bool countCollection,
|
||||
GCCause::Cause cause) {
|
||||
GCCause::Cause cause,
|
||||
bool allMemoryPoolsAffected) {
|
||||
if (recordAccumulatedGCTime) {
|
||||
_accumulated_timer.stop();
|
||||
}
|
||||
@ -259,9 +271,11 @@ void GCMemoryManager::gc_end(bool recordPostGCUsage,
|
||||
MemoryPool* pool = get_memory_pool(i);
|
||||
MemoryUsage usage = pool->get_memory_usage();
|
||||
|
||||
// Compare with GC usage threshold
|
||||
pool->set_last_collection_usage(usage);
|
||||
LowMemoryDetector::detect_after_gc_memory(pool);
|
||||
if (allMemoryPoolsAffected || pool_always_affected_by_gc(i)) {
|
||||
// Compare with GC usage threshold
|
||||
pool->set_last_collection_usage(usage);
|
||||
LowMemoryDetector::detect_after_gc_memory(pool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,11 +45,12 @@ class GCMemoryManager;
|
||||
class OopClosure;
|
||||
|
||||
class MemoryManager : public CHeapObj<mtInternal> {
|
||||
private:
|
||||
protected:
|
||||
enum {
|
||||
max_num_pools = 10
|
||||
};
|
||||
|
||||
private:
|
||||
MemoryPool* _pools[max_num_pools];
|
||||
int _num_pools;
|
||||
|
||||
@ -67,7 +68,7 @@ public:
|
||||
return _pools[index];
|
||||
}
|
||||
|
||||
void add_pool(MemoryPool* pool);
|
||||
int add_pool(MemoryPool* pool);
|
||||
|
||||
bool is_manager(instanceHandle mh) { return oopDesc::equals(mh(), _memory_mgr_obj); }
|
||||
|
||||
@ -142,11 +143,21 @@ private:
|
||||
GCStatInfo* _current_gc_stat;
|
||||
int _num_gc_threads;
|
||||
volatile bool _notification_enabled;
|
||||
const char* _gc_end_message;
|
||||
const char* _gc_end_message;
|
||||
bool _pool_always_affected_by_gc[MemoryManager::max_num_pools];
|
||||
|
||||
public:
|
||||
GCMemoryManager(const char* name, const char* gc_end_message);
|
||||
~GCMemoryManager();
|
||||
|
||||
void add_pool(MemoryPool* pool);
|
||||
void add_pool(MemoryPool* pool, bool always_affected_by_gc);
|
||||
|
||||
bool pool_always_affected_by_gc(int index) {
|
||||
assert(index >= 0 && index < num_memory_pools(), "Invalid index");
|
||||
return _pool_always_affected_by_gc[index];
|
||||
}
|
||||
|
||||
void initialize_gc_stat_info();
|
||||
|
||||
bool is_gc_memory_manager() { return true; }
|
||||
@ -158,7 +169,8 @@ public:
|
||||
void gc_begin(bool recordGCBeginTime, bool recordPreGCUsage,
|
||||
bool recordAccumulatedGCTime);
|
||||
void gc_end(bool recordPostGCUsage, bool recordAccumulatedGCTime,
|
||||
bool recordGCEndTime, bool countCollection, GCCause::Cause cause);
|
||||
bool recordGCEndTime, bool countCollection, GCCause::Cause cause,
|
||||
bool allMemoryPoolsAffected);
|
||||
|
||||
void reset_gc_stat() { _num_collections = 0; _accumulated_timer.reset(); }
|
||||
|
||||
|
@ -182,10 +182,11 @@ void MemoryService::gc_begin(GCMemoryManager* manager, bool recordGCBeginTime,
|
||||
void MemoryService::gc_end(GCMemoryManager* manager, bool recordPostGCUsage,
|
||||
bool recordAccumulatedGCTime,
|
||||
bool recordGCEndTime, bool countCollection,
|
||||
GCCause::Cause cause) {
|
||||
GCCause::Cause cause,
|
||||
bool allMemoryPoolsAffected) {
|
||||
// register the GC end statistics and memory usage
|
||||
manager->gc_end(recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime,
|
||||
countCollection, cause);
|
||||
countCollection, cause, allMemoryPoolsAffected);
|
||||
}
|
||||
|
||||
void MemoryService::oops_do(OopClosure* f) {
|
||||
@ -232,6 +233,7 @@ Handle MemoryService::create_MemoryUsage_obj(MemoryUsage usage, TRAPS) {
|
||||
|
||||
TraceMemoryManagerStats::TraceMemoryManagerStats(GCMemoryManager* gc_memory_manager,
|
||||
GCCause::Cause cause,
|
||||
bool allMemoryPoolsAffected,
|
||||
bool recordGCBeginTime,
|
||||
bool recordPreGCUsage,
|
||||
bool recordPeakUsage,
|
||||
@ -239,7 +241,8 @@ TraceMemoryManagerStats::TraceMemoryManagerStats(GCMemoryManager* gc_memory_mana
|
||||
bool recordAccumulatedGCTime,
|
||||
bool recordGCEndTime,
|
||||
bool countCollection) {
|
||||
initialize(gc_memory_manager, cause, recordGCBeginTime, recordPreGCUsage, recordPeakUsage,
|
||||
initialize(gc_memory_manager, cause, allMemoryPoolsAffected,
|
||||
recordGCBeginTime, recordPreGCUsage, recordPeakUsage,
|
||||
recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime,
|
||||
countCollection);
|
||||
}
|
||||
@ -248,6 +251,7 @@ TraceMemoryManagerStats::TraceMemoryManagerStats(GCMemoryManager* gc_memory_mana
|
||||
// the MemoryService
|
||||
void TraceMemoryManagerStats::initialize(GCMemoryManager* gc_memory_manager,
|
||||
GCCause::Cause cause,
|
||||
bool allMemoryPoolsAffected,
|
||||
bool recordGCBeginTime,
|
||||
bool recordPreGCUsage,
|
||||
bool recordPeakUsage,
|
||||
@ -256,6 +260,7 @@ void TraceMemoryManagerStats::initialize(GCMemoryManager* gc_memory_manager,
|
||||
bool recordGCEndTime,
|
||||
bool countCollection) {
|
||||
_gc_memory_manager = gc_memory_manager;
|
||||
_allMemoryPoolsAffected = allMemoryPoolsAffected;
|
||||
_recordGCBeginTime = recordGCBeginTime;
|
||||
_recordPreGCUsage = recordPreGCUsage;
|
||||
_recordPeakUsage = recordPeakUsage;
|
||||
@ -271,5 +276,5 @@ void TraceMemoryManagerStats::initialize(GCMemoryManager* gc_memory_manager,
|
||||
|
||||
TraceMemoryManagerStats::~TraceMemoryManagerStats() {
|
||||
MemoryService::gc_end(_gc_memory_manager, _recordPostGCUsage, _recordAccumulatedGCTime,
|
||||
_recordGCEndTime, _countCollection, _cause);
|
||||
_recordGCEndTime, _countCollection, _cause, _allMemoryPoolsAffected);
|
||||
}
|
||||
|
@ -102,7 +102,8 @@ public:
|
||||
static void gc_end(GCMemoryManager* manager, bool recordPostGCUsage,
|
||||
bool recordAccumulatedGCTime,
|
||||
bool recordGCEndTime, bool countCollection,
|
||||
GCCause::Cause cause);
|
||||
GCCause::Cause cause,
|
||||
bool allMemoryPoolsAffected);
|
||||
|
||||
static void oops_do(OopClosure* f);
|
||||
|
||||
@ -116,6 +117,7 @@ public:
|
||||
class TraceMemoryManagerStats : public StackObj {
|
||||
private:
|
||||
GCMemoryManager* _gc_memory_manager;
|
||||
bool _allMemoryPoolsAffected;
|
||||
bool _recordGCBeginTime;
|
||||
bool _recordPreGCUsage;
|
||||
bool _recordPeakUsage;
|
||||
@ -128,6 +130,7 @@ public:
|
||||
TraceMemoryManagerStats() {}
|
||||
TraceMemoryManagerStats(GCMemoryManager* gc_memory_manager,
|
||||
GCCause::Cause cause,
|
||||
bool allMemoryPoolsAffected = true,
|
||||
bool recordGCBeginTime = true,
|
||||
bool recordPreGCUsage = true,
|
||||
bool recordPeakUsage = true,
|
||||
@ -138,6 +141,7 @@ public:
|
||||
|
||||
void initialize(GCMemoryManager* gc_memory_manager,
|
||||
GCCause::Cause cause,
|
||||
bool allMemoryPoolsAffected,
|
||||
bool recordGCBeginTime,
|
||||
bool recordPreGCUsage,
|
||||
bool recordPeakUsage,
|
||||
|
@ -86,7 +86,7 @@ public class TestMemoryMXBeansAndPoolsPresence {
|
||||
public static void main(String[] args) {
|
||||
switch (args[0]) {
|
||||
case "G1":
|
||||
test(new GCBeanDescription("G1 Young Generation", new String[] {"G1 Eden Space", "G1 Survivor Space"}),
|
||||
test(new GCBeanDescription("G1 Young Generation", new String[] {"G1 Eden Space", "G1 Survivor Space", "G1 Old Gen"}),
|
||||
new GCBeanDescription("G1 Old Generation", new String[] {"G1 Eden Space", "G1 Survivor Space", "G1 Old Gen"}));
|
||||
break;
|
||||
case "CMS":
|
||||
|
221
test/hotspot/jtreg/gc/g1/mixedgc/TestOldGenCollectionUsage.java
Normal file
221
test/hotspot/jtreg/gc/g1/mixedgc/TestOldGenCollectionUsage.java
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test TestOldGenCollectionUsage.java
|
||||
* @bug 8195115
|
||||
* @summary G1 Old Gen's CollectionUsage.used is zero after mixed GC which is incorrect
|
||||
* @key gc
|
||||
* @requires vm.gc.G1
|
||||
* @requires vm.opt.MaxGCPauseMillis == "null"
|
||||
* @library /test/lib
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @modules java.management
|
||||
* @build sun.hotspot.WhiteBox
|
||||
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -verbose:gc -XX:SurvivorRatio=1 -Xmx12m -Xms12m -XX:MaxTenuringThreshold=1 -XX:InitiatingHeapOccupancyPercent=100 -XX:-G1UseAdaptiveIHOP -XX:G1MixedGCCountTarget=4 -XX:MaxGCPauseMillis=30000 -XX:G1HeapRegionSize=1m -XX:G1HeapWastePercent=0 -XX:G1MixedGCLiveThresholdPercent=100 TestOldGenCollectionUsage
|
||||
*/
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import sun.hotspot.WhiteBox;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
||||
import java.lang.management.*;
|
||||
|
||||
// 8195115 says that for the "G1 Old Gen" MemoryPool, CollectionUsage.used
|
||||
// is zero for G1 after a mixed collection, which is incorrect.
|
||||
|
||||
public class TestOldGenCollectionUsage {
|
||||
|
||||
private String poolName = "G1 Old Gen";
|
||||
private String collectorName = "G1 Young Generation";
|
||||
|
||||
public static void main(String [] args) throws Exception {
|
||||
TestOldGenCollectionUsage t = new TestOldGenCollectionUsage();
|
||||
t.run();
|
||||
}
|
||||
|
||||
public TestOldGenCollectionUsage() {
|
||||
System.out.println("Monitor G1 Old Gen pool with G1 Young Generation collector.");
|
||||
}
|
||||
|
||||
public void run() {
|
||||
// Find memory pool and collector
|
||||
List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
|
||||
MemoryPoolMXBean pool = null;
|
||||
boolean foundPool = false;
|
||||
for (int i = 0; i < pools.size(); i++) {
|
||||
pool = pools.get(i);
|
||||
String name = pool.getName();
|
||||
if (name.contains(poolName)) {
|
||||
System.out.println("Found pool: " + name);
|
||||
foundPool = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundPool) {
|
||||
throw new RuntimeException(poolName + " not found, test with -XX:+UseG1GC");
|
||||
}
|
||||
|
||||
List<GarbageCollectorMXBean> collectors = ManagementFactory.getGarbageCollectorMXBeans();
|
||||
GarbageCollectorMXBean collector = null;
|
||||
boolean foundCollector = false;
|
||||
for (int i = 0; i < collectors.size(); i++) {
|
||||
collector = collectors.get(i);
|
||||
String name = collector.getName();
|
||||
if (name.contains(collectorName)) {
|
||||
System.out.println("Found collector: " + name);
|
||||
foundCollector = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundCollector) {
|
||||
throw new RuntimeException(collectorName + " not found, test with -XX:+UseG1GC");
|
||||
}
|
||||
|
||||
MixedGCProvoker gcProvoker = new MixedGCProvoker();
|
||||
gcProvoker.allocateOldObjects();
|
||||
|
||||
// Verify no non-zero result was stored
|
||||
long usage = pool.getCollectionUsage().getUsed();
|
||||
System.out.println(poolName + ": usage after GC = " + usage);
|
||||
if (usage > 0) {
|
||||
throw new RuntimeException("Premature mixed collections(s)");
|
||||
}
|
||||
|
||||
// Verify that collections were done
|
||||
long collectionCount = collector.getCollectionCount();
|
||||
System.out.println(collectorName + ": collection count = "
|
||||
+ collectionCount);
|
||||
long collectionTime = collector.getCollectionTime();
|
||||
System.out.println(collectorName + ": collection time = "
|
||||
+ collectionTime);
|
||||
if (collectionCount <= 0) {
|
||||
throw new RuntimeException("Collection count <= 0");
|
||||
}
|
||||
if (collectionTime <= 0) {
|
||||
throw new RuntimeException("Collector has not run");
|
||||
}
|
||||
|
||||
gcProvoker.provokeMixedGC();
|
||||
|
||||
usage = pool.getCollectionUsage().getUsed();
|
||||
System.out.println(poolName + ": usage after GC = " + usage);
|
||||
if (usage <= 0) {
|
||||
throw new RuntimeException(poolName + " found with zero usage");
|
||||
}
|
||||
|
||||
long newCollectionCount = collector.getCollectionCount();
|
||||
System.out.println(collectorName + ": collection count = "
|
||||
+ newCollectionCount);
|
||||
long newCollectionTime = collector.getCollectionTime();
|
||||
System.out.println(collectorName + ": collection time = "
|
||||
+ newCollectionTime);
|
||||
if (newCollectionCount <= collectionCount) {
|
||||
throw new RuntimeException("No new collection");
|
||||
}
|
||||
if (newCollectionTime <= collectionTime) {
|
||||
throw new RuntimeException("Collector has not run some more");
|
||||
}
|
||||
|
||||
System.out.println("Test passed.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility class to guarantee a mixed GC. The class allocates several arrays and
|
||||
* promotes them to the oldgen. After that it tries to provoke mixed GC by
|
||||
* allocating new objects.
|
||||
*
|
||||
* The necessary condition for guaranteed mixed GC is running MixedGCProvoker is
|
||||
* running in VM with the following flags: -XX:MaxTenuringThreshold=1 -Xms12M
|
||||
* -Xmx12M -XX:G1MixedGCLiveThresholdPercent=100 -XX:G1HeapWastePercent=0
|
||||
* -XX:G1HeapRegionSize=1m
|
||||
*/
|
||||
public class MixedGCProvoker {
|
||||
private final WhiteBox WB = WhiteBox.getWhiteBox();
|
||||
private final List<byte[]> liveOldObjects = new ArrayList<>();
|
||||
private final List<byte[]> newObjects = new ArrayList<>();
|
||||
|
||||
public static final int ALLOCATION_SIZE = 20000;
|
||||
public static final int ALLOCATION_COUNT = 15;
|
||||
|
||||
public void allocateOldObjects() {
|
||||
List<byte[]> deadOldObjects = new ArrayList<>();
|
||||
// Allocates buffer and promotes it to the old gen. Mix live and dead old
|
||||
// objects
|
||||
for (int i = 0; i < ALLOCATION_COUNT; ++i) {
|
||||
liveOldObjects.add(new byte[ALLOCATION_SIZE * 5]);
|
||||
deadOldObjects.add(new byte[ALLOCATION_SIZE * 5]);
|
||||
}
|
||||
|
||||
// Do two young collections, MaxTenuringThreshold=1 will force promotion.
|
||||
// G1HeapRegionSize=1m guarantees that old gen regions will be filled.
|
||||
WB.youngGC();
|
||||
WB.youngGC();
|
||||
// Check it is promoted & keep alive
|
||||
Asserts.assertTrue(WB.isObjectInOldGen(liveOldObjects),
|
||||
"List of the objects is suppose to be in OldGen");
|
||||
Asserts.assertTrue(WB.isObjectInOldGen(deadOldObjects),
|
||||
"List of the objects is suppose to be in OldGen");
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until Concurent Mark Cycle finishes
|
||||
* @param wb Whitebox instance
|
||||
* @param sleepTime sleep time
|
||||
*/
|
||||
private void waitTillCMCFinished(int sleepTime) {
|
||||
while (WB.g1InConcurrentMark()) {
|
||||
if (sleepTime > -1) {
|
||||
try {
|
||||
Thread.sleep(sleepTime);
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Got InterruptedException while waiting for ConcMarkCycle to finish");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void provokeMixedGC() {
|
||||
waitTillCMCFinished(0);
|
||||
WB.g1StartConcMarkCycle();
|
||||
waitTillCMCFinished(0);
|
||||
WB.youngGC();
|
||||
|
||||
System.out.println("Allocating new objects to provoke mixed GC");
|
||||
// Provoke a mixed collection. G1MixedGCLiveThresholdPercent=100
|
||||
// guarantees that full old gen regions will be included.
|
||||
for (int i = 0; i < (ALLOCATION_COUNT * 20); i++) {
|
||||
newObjects.add(new byte[ALLOCATION_SIZE]);
|
||||
}
|
||||
// check that liveOldObjects still alive
|
||||
Asserts.assertTrue(WB.isObjectInOldGen(liveOldObjects),
|
||||
"List of the objects is suppose to be in OldGen");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user