本文整理汇总了C++中GenCollectedHeap::no_gc_in_progress方法的典型用法代码示例。如果您正苦于以下问题:C++ GenCollectedHeap::no_gc_in_progress方法的具体用法?C++ GenCollectedHeap::no_gc_in_progress怎么用?C++ GenCollectedHeap::no_gc_in_progress使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GenCollectedHeap
的用法示例。
在下文中一共展示了GenCollectedHeap::no_gc_in_progress方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: mem_allocate_work
HeapWord* TwoGenerationCollectorPolicy::mem_allocate_work(size_t size,
bool is_large_noref,
bool is_tlab) {
GenCollectedHeap *gch = GenCollectedHeap::heap();
debug_only(gch->check_for_valid_allocation_state());
assert(gch->no_gc_in_progress(), "Allocation during gc not allowed");
HeapWord* result = NULL;
// Loop until the allocation is satisified,
// or unsatisfied after GC.
for (int try_count = 1; /* return or throw */; try_count += 1) {
// First allocation attempt is lock-free.
Generation *gen0 = gch->get_gen(0);
assert(gen0->supports_inline_contig_alloc(),
"Otherwise, must do alloc within heap lock");
if (gen0->should_allocate(size, is_large_noref, is_tlab)) {
result = gen0->par_allocate(size, is_large_noref, is_tlab);
if (result != NULL) {
assert(gch->is_in(result), "result not in heap");
return result;
}
}
int gc_count_before; // read inside the Heap_lock locked region
{
MutexLocker ml(Heap_lock);
if (PrintGC && Verbose) {
gclog_or_tty->print_cr("TwoGenerationCollectorPolicy::mem_allocate_work:"
" attempting locked slow path allocation");
}
// Note that only large objects get a shot at being
// allocated in later generations. If jvmpi slow allocation
// is enabled, allocate in later generations (since the
// first generation is always full.
bool first_only = ! should_try_older_generation_allocation(size);
result = gch->attempt_allocation(size,
is_large_noref,
is_tlab,
first_only);
if (result != NULL) {
assert(gch->is_in(result), "result not in heap");
return result;
}
// Read the gc count while the heap lock is held.
gc_count_before = Universe::heap()->total_collections();
}
VM_GenCollectForAllocation op(size,
is_large_noref,
is_tlab,
gc_count_before);
VMThread::execute(&op);
if (op.prologue_succeeded()) {
result = op.result();
assert(result == NULL || gch->is_in(result), "result not in heap");
return result;
}
// Give a warning if we seem to be looping forever.
if ((QueuedAllocationWarningCount > 0) &&
(try_count % QueuedAllocationWarningCount == 0)) {
warning("TwoGenerationCollectorPolicy::mem_allocate_work retries %d times \n\t"
" size=%d %s", try_count, size, is_tlab ? "(TLAB)" : "");
}
}
}
示例2: mem_allocate_work
HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
bool is_tlab,
bool* gc_overhead_limit_was_exceeded) {
GenCollectedHeap *gch = GenCollectedHeap::heap();
debug_only(gch->check_for_valid_allocation_state());
assert(gch->no_gc_in_progress(), "Allocation during gc not allowed");
// In general gc_overhead_limit_was_exceeded should be false so
// set it so here and reset it to true only if the gc time
// limit is being exceeded as checked below.
*gc_overhead_limit_was_exceeded = false;
HeapWord* result = NULL;
// Loop until the allocation is satisified,
// or unsatisfied after GC.
for (int try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) {
HandleMark hm; // discard any handles allocated in each iteration
// First allocation attempt is lock-free.
Generation *gen0 = gch->get_gen(0);
assert(gen0->supports_inline_contig_alloc(),
"Otherwise, must do alloc within heap lock");
if (gen0->should_allocate(size, is_tlab)) {
result = gen0->par_allocate(size, is_tlab);
if (result != NULL) {
assert(gch->is_in_reserved(result), "result not in heap");
return result;
}
}
unsigned int gc_count_before; // read inside the Heap_lock locked region
{
MutexLocker ml(Heap_lock);
if (PrintGC && Verbose) {
gclog_or_tty->print_cr("TwoGenerationCollectorPolicy::mem_allocate_work:"
" attempting locked slow path allocation");
}
// Note that only large objects get a shot at being
// allocated in later generations.
bool first_only = ! should_try_older_generation_allocation(size);
result = gch->attempt_allocation(size, is_tlab, first_only);
if (result != NULL) {
assert(gch->is_in_reserved(result), "result not in heap");
return result;
}
if (GC_locker::is_active_and_needs_gc()) {
if (is_tlab) {
return NULL; // Caller will retry allocating individual object
}
if (!gch->is_maximal_no_gc()) {
// Try and expand heap to satisfy request
result = expand_heap_and_allocate(size, is_tlab);
// result could be null if we are out of space
if (result != NULL) {
return result;
}
}
if (gclocker_stalled_count > GCLockerRetryAllocationCount) {
return NULL; // we didn't get to do a GC and we didn't get any memory
}
// If this thread is not in a jni critical section, we stall
// the requestor until the critical section has cleared and
// GC allowed. When the critical section clears, a GC is
// initiated by the last thread exiting the critical section; so
// we retry the allocation sequence from the beginning of the loop,
// rather than causing more, now probably unnecessary, GC attempts.
JavaThread* jthr = JavaThread::current();
if (!jthr->in_critical()) {
MutexUnlocker mul(Heap_lock);
// Wait for JNI critical section to be exited
GC_locker::stall_until_clear();
gclocker_stalled_count += 1;
continue;
} else {
if (CheckJNICalls) {
fatal("Possible deadlock due to allocating while"
" in jni critical section");
}
return NULL;
}
}
// Read the gc count while the heap lock is held.
gc_count_before = Universe::heap()->total_collections();
}
VM_GenCollectForAllocation op(size, is_tlab, gc_count_before);
VMThread::execute(&op);
if (op.prologue_succeeded()) {
result = op.result();
if (op.gc_locked()) {
assert(result == NULL, "must be NULL if gc_locked() is true");
continue; // retry and/or stall as necessary
}
//.........这里部分代码省略.........
示例3: mem_allocate_work
/**
* 分配指定大小的内存空间,基于内存分代的分配策略(轮寻式):
* 1.(无锁式)年青代快速分配
* 2.(加锁式)
* 1).抢占内存堆全局锁
* 2).如果请求的内存大小>年青代内存容量 || Gc被触发但无法被执行 || 增量式Gc会失败, 则依次尝试从年青代-老年代分配内存
* 否则,只从年青代分配内存
* 3).如果Gc被触发但目前还无法被执行:
* a).如果某一内存代还可扩展其内存容量,则依次从老年代-年青代尝试扩展内存分配
* b).释放内存堆全局锁,并等待Gc被执行完成
* 4).释放内存堆全局锁,触发一次GC操作请求,并等待其被执行或放弃
* 5).如果Gc被放弃或由于Gc锁被禁止执行,则回到1
* 6).如果Gc超时,返回NULL,否则返回分配的内存块
*
*
* @param size 申请的内存空间大小
* @param is_tlab false: 从内存堆中分配内存空间
* true: 从当前线程的本地分配缓冲区中分配内存空间
* @gc_overhead_limit_was_exceeded Full Gc是否超时
*
*/
HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size, bool is_tlab,
bool* gc_overhead_limit_was_exceeded) {
GenCollectedHeap *gch = GenCollectedHeap::heap();
debug_only(gch->check_for_valid_allocation_state());
//确保当前JVM没有正在进行GC
assert(gch->no_gc_in_progress(), "Allocation during gc not allowed");
// In general gc_overhead_limit_was_exceeded should be false so
// set it so here and reset it to true only if the gc time
// limit is being exceeded as checked below.
*gc_overhead_limit_was_exceeded = false;
HeapWord* result = NULL;
// Loop until the allocation is satisified,
// or unsatisfied after GC.
for (int try_count = 1; /* return or throw */; try_count += 1) {
HandleMark hm; // discard any handles allocated in each iteration
//年青代必须支持无锁并发方式的内存分配
Generation *gen0 = gch->get_gen(0);
assert(gen0->supports_inline_contig_alloc(), "Otherwise, must do alloc within heap lock");
//当前是否应该优先考虑从年青代分配内存
if (gen0->should_allocate(size, is_tlab)) {
//试图从年青代快速分配内存块
result = gen0->par_allocate(size, is_tlab);
if (result != NULL) {
assert(gch->is_in_reserved(result), "result not in heap");
return result;
}
}
unsigned int gc_count_before; // read inside the Heap_lock locked region
{
MutexLocker ml(Heap_lock);
if (PrintGC && Verbose) {
gclog_or_tty->print_cr("TwoGenerationCollectorPolicy::mem_allocate_work:"
" attempting locked slow path allocation");
}
// Note that only large objects get a shot at being
// allocated in later generations.
//当前是否应该只在年青代分配内存
bool first_only = ! should_try_older_generation_allocation(size);
//依次尝试从内存堆的各内存代中分配内存空间
result = gch->attempt_allocation(size, is_tlab, first_only);
if (result != NULL) {
assert(gch->is_in_reserved(result), "result not in heap");
return result;
}
if (GC_locker::is_active_and_needs_gc()) { //当前其它线程已经触发了Gc
if (is_tlab) {
//当前线程是为本地分配缓冲区申请内存(进而再从本地分配缓冲区为对象分配内存),则返回NULL,
//以让其直接从内存代中为对象申请内存
return NULL;
}
if (!gch->is_maximal_no_gc()) { //内存堆中的某一个内存代允许扩展其大小
//在允许扩展内存代大小的情况下尝试从内存堆的各内存代中分配内存空间
result = expand_heap_and_allocate(size, is_tlab);
// result could be null if we are out of space
if (result != NULL) {
return result;
}
}
// If this thread is not in a jni critical section, we stall
// the requestor until the critical section has cleared and
// GC allowed. When the critical section clears, a GC is
// initiated by the last thread exiting the critical section; so
// we retry the allocation sequence from the beginning of the loop,
// rather than causing more, now probably unnecessary, GC attempts.
JavaThread* jthr = JavaThread::current();
//.........这里部分代码省略.........