1 #ifdef USE_PRAGMA_IDENT_SRC
2 #pragma ident "@(#)permGen.cpp 1.54 07/05/29 09:44:16 JVM"
3 #endif
4 /*
5 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 *
8 * This code is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 only, as
10 * published by the Free Software Foundation.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
24 * have any questions.
25 *
26 */
27
28 #include "incls/_precompiled.incl"
29 #include "incls/_permGen.cpp.incl"
30
31 CompactingPermGen::CompactingPermGen(ReservedSpace rs,
32 ReservedSpace shared_rs,
33 size_t initial_byte_size,
34 GenRemSet* remset,
35 PermanentGenerationSpec* perm_spec)
36 {
37 CompactingPermGenGen* g =
38 new CompactingPermGenGen(rs, shared_rs, initial_byte_size, -1, remset,
39 NULL, perm_spec);
40 if (g == NULL)
41 vm_exit_during_initialization("Could not allocate a CompactingPermGen");
42 _gen = g;
43
44 g->initialize_performance_counters();
45
46 _capacity_expansion_limit = g->capacity() + MaxPermHeapExpansion;
47 }
48
49 HeapWord* CompactingPermGen::mem_allocate(size_t size) {
50 MutexLocker ml(Heap_lock);
51 HeapWord* obj = _gen->allocate(size, false);
52 bool tried_collection = false;
53 bool tried_expansion = false;
54 while (obj == NULL) {
55 if (_gen->capacity() >= _capacity_expansion_limit || tried_expansion) {
56 // Expansion limit reached, try collection before expanding further
57 // For now we force a full collection, this could be changed
58 SharedHeap::heap()->collect_locked(GCCause::_permanent_generation_full);
59 obj = _gen->allocate(size, false);
60 tried_collection = true;
61 tried_expansion = false; // ... following the collection:
62 // the collection may have shrunk the space.
63 }
64 if (obj == NULL && !tried_expansion) {
65 obj = _gen->expand_and_allocate(size, false);
66 tried_expansion = true;
67 }
68 if (obj == NULL && tried_collection && tried_expansion) {
69 // We have not been able to allocate despite a collection and
70 // an attempted space expansion. We now make a last-ditch collection
71 // attempt that will try to reclaim as much space as possible (for
72 // example by aggressively clearing all soft refs).
73 SharedHeap::heap()->collect_locked(GCCause::_last_ditch_collection);
74 obj = _gen->allocate(size, false);
75 if (obj == NULL) {
76 // An expansion attempt is necessary since the previous
77 // collection may have shrunk the space.
78 obj = _gen->expand_and_allocate(size, false);
79 }
80 break;
81 }
82 }
83 return obj;
84 }
85
86 void CompactingPermGen::compute_new_size() {
87 size_t desired_capacity = align_size_up(_gen->used(), MinPermHeapExpansion);
88 if (desired_capacity < PermSize) {
89 desired_capacity = PermSize;
90 }
91 if (_gen->capacity() > desired_capacity) {
92 _gen->shrink(_gen->capacity() - desired_capacity);
93 }
94 _capacity_expansion_limit = _gen->capacity() + MaxPermHeapExpansion;
95 }
|
1 #ifdef USE_PRAGMA_IDENT_SRC
2 #pragma ident "@(#)permGen.cpp 1.54 07/05/29 09:44:16 JVM"
3 #endif
4 /*
5 * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 *
8 * This code is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 only, as
10 * published by the Free Software Foundation.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
24 * have any questions.
25 *
26 */
27
28 #include "incls/_precompiled.incl"
29 #include "incls/_permGen.cpp.incl"
30
31 HeapWord* PermGen::mem_allocate_in_gen(size_t size, Generation* gen) {
32 GCCause::Cause next_cause = GCCause::_permanent_generation_full;
33 GCCause::Cause prev_cause = GCCause::_no_gc;
34 unsigned int gc_count_before, full_gc_count_before;
35 HeapWord* obj;
36
37 for (;;) {
38 {
39 MutexLocker ml(Heap_lock);
40 if ((obj = gen->allocate(size, false)) != NULL) {
41 return obj;
42 }
43 if (gen->capacity() < _capacity_expansion_limit ||
44 prev_cause != GCCause::_no_gc) {
45 obj = gen->expand_and_allocate(size, false);
46 }
47 if (obj != NULL || prev_cause == GCCause::_last_ditch_collection) {
48 return obj;
49 }
50 if (GC_locker::is_active_and_needs_gc()) {
51 // If this thread is not in a jni critical section, we stall
52 // the requestor until the critical section has cleared and
53 // GC allowed. When the critical section clears, a GC is
54 // initiated by the last thread exiting the critical section; so
55 // we retry the allocation sequence from the beginning of the loop,
56 // rather than causing more, now probably unnecessary, GC attempts.
57 JavaThread* jthr = JavaThread::current();
58 if (!jthr->in_critical()) {
59 MutexUnlocker mul(Heap_lock);
60 // Wait for JNI critical section to be exited
61 GC_locker::stall_until_clear();
62 continue;
63 } else {
64 if (CheckJNICalls) {
65 fatal("Possible deadlock due to allocating while"
66 " in jni critical section");
67 }
68 return NULL;
69 }
70 }
71 // Read the GC count while holding the Heap_lock
72 gc_count_before = SharedHeap::heap()->total_collections();
73 full_gc_count_before = SharedHeap::heap()->total_full_collections();
74 }
75
76 // Give up heap lock above, VMThread::execute below gets it back
77 VM_GenCollectForPermanentAllocation op(size, gc_count_before, full_gc_count_before,
78 next_cause);
79 VMThread::execute(&op);
80 if (!op.prologue_succeeded() || op.gc_locked()) {
81 assert(op.result() == NULL, "must be NULL if gc_locked() is true");
82 continue; // retry and/or stall as necessary
83 }
84 obj = op.result();
85 assert(obj == NULL || SharedHeap::heap()->is_in_reserved(obj),
86 "result not in heap");
87 if (obj != NULL) {
88 return obj;
89 }
90 prev_cause = next_cause;
91 next_cause = GCCause::_last_ditch_collection;
92 }
93 }
94
95 CompactingPermGen::CompactingPermGen(ReservedSpace rs,
96 ReservedSpace shared_rs,
97 size_t initial_byte_size,
98 GenRemSet* remset,
99 PermanentGenerationSpec* perm_spec)
100 {
101 CompactingPermGenGen* g =
102 new CompactingPermGenGen(rs, shared_rs, initial_byte_size, -1, remset,
103 NULL, perm_spec);
104 if (g == NULL)
105 vm_exit_during_initialization("Could not allocate a CompactingPermGen");
106 _gen = g;
107
108 g->initialize_performance_counters();
109
110 _capacity_expansion_limit = g->capacity() + MaxPermHeapExpansion;
111 }
112
113 HeapWord* CompactingPermGen::mem_allocate(size_t size) {
114 return mem_allocate_in_gen(size, _gen);
115 }
116
117 void CompactingPermGen::compute_new_size() {
118 size_t desired_capacity = align_size_up(_gen->used(), MinPermHeapExpansion);
119 if (desired_capacity < PermSize) {
120 desired_capacity = PermSize;
121 }
122 if (_gen->capacity() > desired_capacity) {
123 _gen->shrink(_gen->capacity() - desired_capacity);
124 }
125 _capacity_expansion_limit = _gen->capacity() + MaxPermHeapExpansion;
126 }
|