mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
6964458: Reimplement class meta-data storage to use native memory
Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Co-authored-by: Stefan Karlsson <stefan.karlsson@oracle.com> Co-authored-by: Mikael Gerdin <mikael.gerdin@oracle.com> Co-authored-by: Tom Rodriguez <tom.rodriguez@oracle.com> Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
This commit is contained in:
parent
36eee7c8c8
commit
5c58d27aac
853 changed files with 26124 additions and 82956 deletions
|
@ -32,10 +32,10 @@
|
|||
#include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
|
||||
#include "gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp"
|
||||
#include "gc_implementation/parallelScavenge/psOldGen.hpp"
|
||||
#include "gc_implementation/parallelScavenge/psPermGen.hpp"
|
||||
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
|
||||
#include "gc_implementation/parallelScavenge/psYoungGen.hpp"
|
||||
#include "gc_implementation/shared/isGCActiveMark.hpp"
|
||||
#include "gc_implementation/shared/markSweep.hpp"
|
||||
#include "gc_implementation/shared/spaceDecorator.hpp"
|
||||
#include "gc_interface/gcCause.hpp"
|
||||
#include "memory/gcLocker.inline.hpp"
|
||||
|
@ -52,7 +52,6 @@
|
|||
#include "utilities/stack.inline.hpp"
|
||||
|
||||
elapsedTimer PSMarkSweep::_accumulated_time;
|
||||
unsigned int PSMarkSweep::_total_invocations = 0;
|
||||
jlong PSMarkSweep::_time_of_last_gc = 0;
|
||||
CollectorCounters* PSMarkSweep::_counters = NULL;
|
||||
|
||||
|
@ -119,7 +118,6 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
|||
|
||||
PSYoungGen* young_gen = heap->young_gen();
|
||||
PSOldGen* old_gen = heap->old_gen();
|
||||
PSPermGen* perm_gen = heap->perm_gen();
|
||||
|
||||
// Increment the invocation count
|
||||
heap->increment_total_collections(true /* full */);
|
||||
|
@ -148,7 +146,6 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
|||
if (VerifyObjectStartArray &&
|
||||
VerifyBeforeGC) {
|
||||
old_gen->verify_object_start_array();
|
||||
perm_gen->verify_object_start_array();
|
||||
}
|
||||
|
||||
heap->pre_full_gc_dump();
|
||||
|
@ -172,8 +169,6 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
|||
// Let the size policy know we're starting
|
||||
size_policy->major_collection_begin();
|
||||
|
||||
// When collecting the permanent generation methodOops may be moving,
|
||||
// so we either have to flush all bcp data or convert it into bci.
|
||||
CodeCache::gc_prologue();
|
||||
Threads::gc_prologue();
|
||||
BiasedLocking::preserve_marks();
|
||||
|
@ -181,8 +176,8 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
|||
// Capture heap size before collection for printing.
|
||||
size_t prev_used = heap->used();
|
||||
|
||||
// Capture perm gen size before collection for sizing.
|
||||
size_t perm_gen_prev_used = perm_gen->used_in_bytes();
|
||||
// Capture metadata size before collection for sizing.
|
||||
size_t metadata_prev_used = MetaspaceAux::used_in_bytes();
|
||||
|
||||
// For PrintGCDetails
|
||||
size_t old_gen_prev_used = old_gen->used_in_bytes();
|
||||
|
@ -234,16 +229,16 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
|||
if (bs->is_a(BarrierSet::ModRef)) {
|
||||
ModRefBarrierSet* modBS = (ModRefBarrierSet*)bs;
|
||||
MemRegion old_mr = heap->old_gen()->reserved();
|
||||
MemRegion perm_mr = heap->perm_gen()->reserved();
|
||||
assert(perm_mr.end() <= old_mr.start(), "Generations out of order");
|
||||
|
||||
if (young_gen_empty) {
|
||||
modBS->clear(MemRegion(perm_mr.start(), old_mr.end()));
|
||||
modBS->clear(MemRegion(old_mr.start(), old_mr.end()));
|
||||
} else {
|
||||
modBS->invalidate(MemRegion(perm_mr.start(), old_mr.end()));
|
||||
modBS->invalidate(MemRegion(old_mr.start(), old_mr.end()));
|
||||
}
|
||||
}
|
||||
|
||||
// Delete metaspaces for unloaded class loaders and clean up loader_data graph
|
||||
ClassLoaderDataGraph::purge();
|
||||
|
||||
BiasedLocking::restore_marks();
|
||||
Threads::gc_epilogue();
|
||||
CodeCache::gc_epilogue();
|
||||
|
@ -267,10 +262,8 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
|||
gclog_or_tty->print_cr(" collection: %d ",
|
||||
heap->total_collections());
|
||||
if (Verbose) {
|
||||
gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d"
|
||||
" perm_gen_capacity: %d ",
|
||||
old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes(),
|
||||
perm_gen->capacity_in_bytes());
|
||||
gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d",
|
||||
old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,7 +283,6 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
|||
size_policy->compute_generation_free_space(young_gen->used_in_bytes(),
|
||||
young_gen->eden_space()->used_in_bytes(),
|
||||
old_gen->used_in_bytes(),
|
||||
perm_gen->used_in_bytes(),
|
||||
young_gen->eden_space()->capacity_in_bytes(),
|
||||
old_gen->max_gen_size(),
|
||||
max_eden_size,
|
||||
|
@ -323,8 +315,8 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
|||
|
||||
heap->resize_all_tlabs();
|
||||
|
||||
// We collected the perm gen, so we'll resize it here.
|
||||
perm_gen->compute_new_size(perm_gen_prev_used);
|
||||
// We collected the heap, recalculate the metaspace capacity
|
||||
MetaspaceGC::compute_new_size();
|
||||
|
||||
if (TraceGen1Time) accumulated_time()->stop();
|
||||
|
||||
|
@ -336,11 +328,8 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
|||
old_gen->print_used_change(old_gen_prev_used);
|
||||
}
|
||||
heap->print_heap_change(prev_used);
|
||||
// Do perm gen after heap becase prev_used does
|
||||
// not include the perm gen (done this way in the other
|
||||
// collectors).
|
||||
if (PrintGCDetails) {
|
||||
perm_gen->print_used_change(perm_gen_prev_used);
|
||||
MetaspaceAux::print_metaspace_change(metadata_prev_used);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,12 +348,10 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
|||
if (VerifyObjectStartArray &&
|
||||
VerifyAfterGC) {
|
||||
old_gen->verify_object_start_array();
|
||||
perm_gen->verify_object_start_array();
|
||||
}
|
||||
|
||||
if (ZapUnusedHeapArea) {
|
||||
old_gen->object_space()->check_mangled_unused_area_complete();
|
||||
perm_gen->object_space()->check_mangled_unused_area_complete();
|
||||
}
|
||||
|
||||
NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
|
||||
|
@ -490,8 +477,6 @@ void PSMarkSweep::deallocate_stacks() {
|
|||
_preserved_oop_stack.clear(true);
|
||||
_marking_stack.clear();
|
||||
_objarray_stack.clear(true);
|
||||
_revisit_klass_stack.clear(true);
|
||||
_revisit_mdo_stack.clear(true);
|
||||
}
|
||||
|
||||
void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
|
||||
|
@ -502,6 +487,9 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
|
|||
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
||||
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
|
||||
|
||||
// Need to clear claim bits before the tracing starts.
|
||||
ClassLoaderDataGraph::clear_claimed_marks();
|
||||
|
||||
// General strong roots.
|
||||
{
|
||||
ParallelScavengeHeap::ParStrongRootsScope psrs;
|
||||
|
@ -514,6 +502,7 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
|
|||
Management::oops_do(mark_and_push_closure());
|
||||
JvmtiExport::oops_do(mark_and_push_closure());
|
||||
SystemDictionary::always_strong_oops_do(mark_and_push_closure());
|
||||
ClassLoaderDataGraph::always_strong_oops_do(mark_and_push_closure(), follow_klass_closure(), true);
|
||||
// Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
|
||||
//CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure()));
|
||||
}
|
||||
|
@ -537,11 +526,7 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
|
|||
follow_stack(); // Flush marking stack
|
||||
|
||||
// Update subklass/sibling/implementor links of live klasses
|
||||
follow_weak_klass_links();
|
||||
assert(_marking_stack.is_empty(), "just drained");
|
||||
|
||||
// Visit memoized mdo's and clear unmarked weak refs
|
||||
follow_mdo_weak_refs();
|
||||
Klass::clean_weak_klass_links(&is_alive);
|
||||
assert(_marking_stack.is_empty(), "just drained");
|
||||
|
||||
// Visit interned string tables and delete unmarked oops
|
||||
|
@ -559,13 +544,6 @@ void PSMarkSweep::mark_sweep_phase2() {
|
|||
|
||||
// Now all live objects are marked, compute the new object addresses.
|
||||
|
||||
// It is imperative that we traverse perm_gen LAST. If dead space is
|
||||
// allowed a range of dead object may get overwritten by a dead int
|
||||
// array. If perm_gen is not traversed last a klassOop may get
|
||||
// overwritten. This is fine since it is dead, but if the class has dead
|
||||
// instances we have to skip them, and in order to find their size we
|
||||
// need the klassOop!
|
||||
//
|
||||
// It is not required that we traverse spaces in the same order in
|
||||
// phase2, phase3 and phase4, but the ValidateMarkSweep live oops
|
||||
// tracking expects us to do so. See comment under phase4.
|
||||
|
@ -574,18 +552,12 @@ void PSMarkSweep::mark_sweep_phase2() {
|
|||
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
|
||||
|
||||
PSOldGen* old_gen = heap->old_gen();
|
||||
PSPermGen* perm_gen = heap->perm_gen();
|
||||
|
||||
// Begin compacting into the old gen
|
||||
PSMarkSweepDecorator::set_destination_decorator_tenured();
|
||||
|
||||
// This will also compact the young gen spaces.
|
||||
old_gen->precompact();
|
||||
|
||||
// Compact the perm gen into the perm gen
|
||||
PSMarkSweepDecorator::set_destination_decorator_perm_gen();
|
||||
|
||||
perm_gen->precompact();
|
||||
}
|
||||
|
||||
// This should be moved to the shared markSweep code!
|
||||
|
@ -606,7 +578,9 @@ void PSMarkSweep::mark_sweep_phase3() {
|
|||
|
||||
PSYoungGen* young_gen = heap->young_gen();
|
||||
PSOldGen* old_gen = heap->old_gen();
|
||||
PSPermGen* perm_gen = heap->perm_gen();
|
||||
|
||||
// Need to clear claim bits before the tracing starts.
|
||||
ClassLoaderDataGraph::clear_claimed_marks();
|
||||
|
||||
// General strong roots.
|
||||
Universe::oops_do(adjust_root_pointer_closure());
|
||||
|
@ -618,6 +592,7 @@ void PSMarkSweep::mark_sweep_phase3() {
|
|||
JvmtiExport::oops_do(adjust_root_pointer_closure());
|
||||
// SO_AllClasses
|
||||
SystemDictionary::oops_do(adjust_root_pointer_closure());
|
||||
ClassLoaderDataGraph::oops_do(adjust_root_pointer_closure(), adjust_klass_closure(), true);
|
||||
//CodeCache::scavenge_root_nmethods_oops_do(adjust_root_pointer_closure());
|
||||
|
||||
// Now adjust pointers in remaining weak roots. (All of which should
|
||||
|
@ -634,7 +609,6 @@ void PSMarkSweep::mark_sweep_phase3() {
|
|||
|
||||
young_gen->adjust_pointers();
|
||||
old_gen->adjust_pointers();
|
||||
perm_gen->adjust_pointers();
|
||||
}
|
||||
|
||||
void PSMarkSweep::mark_sweep_phase4() {
|
||||
|
@ -644,18 +618,12 @@ void PSMarkSweep::mark_sweep_phase4() {
|
|||
|
||||
// All pointers are now adjusted, move objects accordingly
|
||||
|
||||
// It is imperative that we traverse perm_gen first in phase4. All
|
||||
// classes must be allocated earlier than their instances, and traversing
|
||||
// perm_gen first makes sure that all klassOops have moved to their new
|
||||
// location before any instance does a dispatch through it's klass!
|
||||
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
||||
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
|
||||
|
||||
PSYoungGen* young_gen = heap->young_gen();
|
||||
PSOldGen* old_gen = heap->old_gen();
|
||||
PSPermGen* perm_gen = heap->perm_gen();
|
||||
|
||||
perm_gen->compact();
|
||||
old_gen->compact();
|
||||
young_gen->compact();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue