$ grep -rn -C 4 GCCause::_no_gc hotspot/src
./share/vm/gc_implementation/shared/vmGCOperations.cpp-86-}
./share/vm/gc_implementation/shared/vmGCOperations.cpp-87-
./share/vm/gc_implementation/shared/vmGCOperations.cpp-88-bool VM_GC_Operation::doit_prologue() {
./share/vm/gc_implementation/shared/vmGCOperations.cpp-89- assert(Thread::current()->is_Java_thread(), "just checking");
./share/vm/gc_implementation/shared/vmGCOperations.cpp:90: assert(((_gc_cause != GCCause::_no_gc) &&
./share/vm/gc_implementation/shared/vmGCOperations.cpp-91- (_gc_cause != GCCause::_no_cause_specified)), "Illegal GCCause");
./share/vm/gc_implementation/shared/vmGCOperations.cpp-92-
./share/vm/gc_implementation/shared/vmGCOperations.cpp-93- acquire_pending_list_lock();
./share/vm/gc_implementation/shared/vmGCOperations.cpp-94- // If the GC count has changed someone beat us to the collection
--
./share/vm/gc_interface/collectedHeap.cpp-60-
./share/vm/gc_interface/collectedHeap.cpp-61- _barrier_set = NULL;
./share/vm/gc_interface/collectedHeap.cpp-62- _is_gc_active = false;
./share/vm/gc_interface/collectedHeap.cpp-63- _total_collections = _total_full_collections = 0;
./share/vm/gc_interface/collectedHeap.cpp:64: _gc_cause = _gc_lastcause = GCCause::_no_gc;
./share/vm/gc_interface/collectedHeap.cpp-65- NOT_PRODUCT(_promotion_failure_alot_count = 0;)
./share/vm/gc_interface/collectedHeap.cpp-66- NOT_PRODUCT(_promotion_failure_alot_gc_number = 0;)
./share/vm/gc_interface/collectedHeap.cpp-67-
./share/vm/gc_interface/collectedHeap.cpp-68- if (UsePerfData) {
--
./share/vm/memory/permGen.cpp-40-
./share/vm/memory/permGen.cpp-41-HeapWord* PermGen::request_expand_and_allocate(Generation* gen, size_t size,
./share/vm/memory/permGen.cpp-42- GCCause::Cause prev_cause) {
./share/vm/memory/permGen.cpp-43- if (gen->capacity() < _capacity_expansion_limit ||
./share/vm/memory/permGen.cpp:44: prev_cause != GCCause::_no_gc || UseG1GC) { // last disjunct is a temporary hack for G1
./share/vm/memory/permGen.cpp-45- return gen->expand_and_allocate(size, false);
./share/vm/memory/permGen.cpp-46- }
./share/vm/memory/permGen.cpp-47- // We have reached the limit of capacity expansion where
./share/vm/memory/permGen.cpp-48- // we will not expand further until a GC is done; request denied.
--
./share/vm/memory/permGen.cpp-50-}
./share/vm/memory/permGen.cpp-51-
./share/vm/memory/permGen.cpp-52-HeapWord* PermGen::mem_allocate_in_gen(size_t size, Generation* gen) {
./share/vm/memory/permGen.cpp-53- GCCause::Cause next_cause = GCCause::_permanent_generation_full;
./share/vm/memory/permGen.cpp:54: GCCause::Cause prev_cause = GCCause::_no_gc;
./share/vm/memory/permGen.cpp-55- unsigned int gc_count_before, full_gc_count_before;
./share/vm/memory/permGen.cpp-56- HeapWord* obj;
./share/vm/memory/permGen.cpp-57-
./share/vm/memory/permGen.cpp-58- for (;;) {
So, we have two reads and two writes. The one in collectedHeap.cpp
is initialization in constructor. The other one is when we are trying to allocate more memory for permgen, apparently:
HeapWord* mem_allocate_in_gen(size_t size, Generation* gen);
// Along with mem_allocate_in_gen() above, implements policy for
// "scheduling" allocation/expansion/collection of the perm gen.
// The virtual method request_...() below can be overridden by
// subtypes that want to implement a different expansion/collection
// policy from the default provided.
Is only invoked once:
HeapWord* CompactingPermGen::mem_allocate(size_t size) {
return mem_allocate_in_gen(size, _gen);
}
As for GCCause::_last_ditch_collection
, it is only set once in the end of PermGen::mem_allocate_in_gen
:
./share/vm/memory/permGen.cpp-115- prev_cause = next_cause;
./share/vm/memory/permGen.cpp:116: next_cause = GCCause::_last_ditch_collection;
./share/vm/memory/permGen.cpp-117- }
See also: