diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp index 9d5929d0c817569e04c7a04f89038680123b5b86..f04b8a46772edc42d6953e266f4ab96032dff663 100644 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, 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 @@ -50,6 +50,18 @@ HeapWord* CMSPermGen::mem_allocate(size_t size) { } } +HeapWord* CMSPermGen::request_expand_and_allocate(Generation* gen, + size_t size, + GCCause::Cause prev_cause /* ignored */) { + HeapWord* obj = gen->expand_and_allocate(size, false); + if (gen->capacity() >= _capacity_expansion_limit) { + set_capacity_expansion_limit(gen->capacity() + MaxPermHeapExpansion); + assert(((ConcurrentMarkSweepGeneration*)gen)->should_concurrent_collect(), + "Should kick off a collection if one not in progress"); + } + return obj; +} + void CMSPermGen::compute_new_size() { _gen->compute_new_size(); } diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp index 3c9d9f7f7677b0dd77ec7ece3702909c31f06ebe..fd675623ea88d06d313ceea20485963653637b83 100644 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp @@ -33,6 +33,10 @@ class CMSPermGen: public PermGen { // The "generation" view. ConcurrentMarkSweepGeneration* _gen; + // Override default implementation from PermGen + virtual HeapWord* request_expand_and_allocate(Generation* gen, size_t size, + GCCause::Cause prev_cause); + public: CMSPermGen(ReservedSpace rs, size_t initial_byte_size, CardTableRS* ct, FreeBlockDictionary::DictionaryChoice); diff --git a/src/share/vm/includeDB_core b/src/share/vm/includeDB_core index 8985a211cc478a096ee225c015ba0b8d3ce48b2e..d1a0f892c1fd58cf843b38e159994f43867052d9 100644 --- a/src/share/vm/includeDB_core +++ b/src/share/vm/includeDB_core @@ -3456,6 +3456,7 @@ permGen.hpp gcCause.hpp permGen.hpp generation.hpp permGen.hpp handles.hpp permGen.hpp iterator.hpp +permGen.hpp mutexLocker.hpp permGen.hpp virtualspace.hpp placeholders.cpp fieldType.hpp diff --git a/src/share/vm/memory/permGen.cpp b/src/share/vm/memory/permGen.cpp index cae72174dcfd970d91accde468c9dd2d6747f0a8..7073aa47d6e1bd3554b736e7593e93b62b734481 100644 --- a/src/share/vm/memory/permGen.cpp +++ b/src/share/vm/memory/permGen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, 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 @@ -25,6 +25,17 @@ #include "incls/_precompiled.incl" #include "incls/_permGen.cpp.incl" +HeapWord* PermGen::request_expand_and_allocate(Generation* gen, size_t size, + GCCause::Cause prev_cause) { + if (gen->capacity() < _capacity_expansion_limit || + prev_cause != GCCause::_no_gc || UseG1GC) { // last disjunct is a temporary hack for G1 + return gen->expand_and_allocate(size, false); + } + // We have reached the limit of capacity expansion where + // we will not expand further until a GC is done; request denied. + return NULL; +} + HeapWord* PermGen::mem_allocate_in_gen(size_t size, Generation* gen) { GCCause::Cause next_cause = GCCause::_permanent_generation_full; GCCause::Cause prev_cause = GCCause::_no_gc; @@ -37,10 +48,14 @@ HeapWord* PermGen::mem_allocate_in_gen(size_t size, Generation* gen) { if ((obj = gen->allocate(size, false)) != NULL) { return obj; } - if (gen->capacity() < _capacity_expansion_limit || - prev_cause != GCCause::_no_gc) { - obj = gen->expand_and_allocate(size, false); - } + // Attempt to expand and allocate the requested space: + // specific subtypes may use specific policy to either expand + // or not. The default policy (see above) is to expand until + // _capacity_expansion_limit, and no further unless a GC is done. + // Concurrent collectors may decide to kick off a concurrent + // collection under appropriate conditions. + obj = request_expand_and_allocate(gen, size, prev_cause); + if (obj != NULL || prev_cause == GCCause::_last_ditch_collection) { return obj; } @@ -119,5 +134,5 @@ void CompactingPermGen::compute_new_size() { if (_gen->capacity() > desired_capacity) { _gen->shrink(_gen->capacity() - desired_capacity); } - _capacity_expansion_limit = _gen->capacity() + MaxPermHeapExpansion; + set_capacity_expansion_limit(_gen->capacity() + MaxPermHeapExpansion); } diff --git a/src/share/vm/memory/permGen.hpp b/src/share/vm/memory/permGen.hpp index 67ce81aeb4290a6a16197c4c633f4a0164a0c6df..a6f54e0f8429d6b9f9cc219003bb9777095bb031 100644 --- a/src/share/vm/memory/permGen.hpp +++ b/src/share/vm/memory/permGen.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, 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 @@ -30,15 +30,26 @@ class Generation; class GenRemSet; class CSpaceCounters; -// PermGen models the part of the heap +// PermGen models the part of the heap used to allocate class meta-data. class PermGen : public CHeapObj { friend class VMStructs; protected: size_t _capacity_expansion_limit; // maximum expansion allowed without a // full gc occurring + void set_capacity_expansion_limit(size_t limit) { + assert_locked_or_safepoint(Heap_lock); + _capacity_expansion_limit = limit; + } 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. + virtual HeapWord* request_expand_and_allocate(Generation* gen, size_t size, + GCCause::Cause prev_cause); public: enum Name {