src/share/vm/services/memoryService.cpp

Thu, 12 Mar 2009 18:16:36 -0700

author
trims
date
Thu, 12 Mar 2009 18:16:36 -0700
changeset 1063
7bb995fbd3c0
parent 777
37f87013dfd8
child 1524
db0d5eba9d20
permissions
-rw-r--r--

Merge

     1 /*
     2  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 # include "incls/_precompiled.incl"
    26 # include "incls/_memoryService.cpp.incl"
    28 GrowableArray<MemoryPool*>* MemoryService::_pools_list =
    29   new (ResourceObj::C_HEAP) GrowableArray<MemoryPool*>(init_pools_list_size, true);
    30 GrowableArray<MemoryManager*>* MemoryService::_managers_list =
    31   new (ResourceObj::C_HEAP) GrowableArray<MemoryManager*>(init_managers_list_size, true);
    33 GCMemoryManager* MemoryService::_minor_gc_manager = NULL;
    34 GCMemoryManager* MemoryService::_major_gc_manager = NULL;
    35 MemoryPool*      MemoryService::_code_heap_pool   = NULL;
    37 class GcThreadCountClosure: public ThreadClosure {
    38  private:
    39   int _count;
    40  public:
    41   GcThreadCountClosure() : _count(0) {};
    42   void do_thread(Thread* thread);
    43   int count() { return _count; }
    44 };
    46 void GcThreadCountClosure::do_thread(Thread* thread) {
    47   _count++;
    48 }
    50 void MemoryService::set_universe_heap(CollectedHeap* heap) {
    51   CollectedHeap::Name kind = heap->kind();
    52   switch (kind) {
    53     case CollectedHeap::GenCollectedHeap : {
    54       add_gen_collected_heap_info(GenCollectedHeap::heap());
    55       break;
    56     }
    57 #ifndef SERIALGC
    58     case CollectedHeap::ParallelScavengeHeap : {
    59       add_parallel_scavenge_heap_info(ParallelScavengeHeap::heap());
    60       break;
    61     }
    62     case CollectedHeap::G1CollectedHeap : {
    63       G1CollectedHeap::g1_unimplemented();
    64       return;
    65     }
    66 #endif // SERIALGC
    67     default: {
    68       guarantee(false, "Unrecognized kind of heap");
    69     }
    70   }
    72   // set the GC thread count
    73   GcThreadCountClosure gctcc;
    74   heap->gc_threads_do(&gctcc);
    75   int count = gctcc.count();
    76   if (count > 0) {
    77     _minor_gc_manager->set_num_gc_threads(count);
    78     _major_gc_manager->set_num_gc_threads(count);
    79   }
    81   // All memory pools and memory managers are initialized.
    82   //
    83   _minor_gc_manager->initialize_gc_stat_info();
    84   _major_gc_manager->initialize_gc_stat_info();
    85 }
    87 // Add memory pools for GenCollectedHeap
    88 // This function currently only supports two generations collected heap.
    89 // The collector for GenCollectedHeap will have two memory managers.
    90 void MemoryService::add_gen_collected_heap_info(GenCollectedHeap* heap) {
    91   CollectorPolicy* policy = heap->collector_policy();
    93   assert(policy->is_two_generation_policy(), "Only support two generations");
    94   guarantee(heap->n_gens() == 2, "Only support two-generation heap");
    96   TwoGenerationCollectorPolicy* two_gen_policy = policy->as_two_generation_policy();
    97   if (two_gen_policy != NULL) {
    98     GenerationSpec** specs = two_gen_policy->generations();
    99     Generation::Name kind = specs[0]->name();
   100     switch (kind) {
   101       case Generation::DefNew:
   102         _minor_gc_manager = MemoryManager::get_copy_memory_manager();
   103         break;
   104 #ifndef SERIALGC
   105       case Generation::ParNew:
   106       case Generation::ASParNew:
   107         _minor_gc_manager = MemoryManager::get_parnew_memory_manager();
   108         break;
   109 #endif // SERIALGC
   110       default:
   111         guarantee(false, "Unrecognized generation spec");
   112         break;
   113     }
   114     if (policy->is_mark_sweep_policy()) {
   115       _major_gc_manager = MemoryManager::get_msc_memory_manager();
   116 #ifndef SERIALGC
   117     } else if (policy->is_concurrent_mark_sweep_policy()) {
   118       _major_gc_manager = MemoryManager::get_cms_memory_manager();
   119 #endif // SERIALGC
   120     } else {
   121       guarantee(false, "Unknown two-gen policy");
   122     }
   123   } else {
   124     guarantee(false, "Non two-gen policy");
   125   }
   126   _managers_list->append(_minor_gc_manager);
   127   _managers_list->append(_major_gc_manager);
   129   add_generation_memory_pool(heap->get_gen(minor), _major_gc_manager, _minor_gc_manager);
   130   add_generation_memory_pool(heap->get_gen(major), _major_gc_manager);
   132   PermGen::Name name = policy->permanent_generation()->name();
   133   switch (name) {
   134     case PermGen::MarkSweepCompact: {
   135       CompactingPermGenGen* perm_gen = (CompactingPermGenGen*) heap->perm_gen();
   136       add_compact_perm_gen_memory_pool(perm_gen, _major_gc_manager);
   137       break;
   138     }
   139 #ifndef SERIALGC
   140     case PermGen::ConcurrentMarkSweep: {
   141       CMSPermGenGen* cms_gen = (CMSPermGenGen*) heap->perm_gen();
   142       add_cms_perm_gen_memory_pool(cms_gen, _major_gc_manager);
   143       break;
   144     }
   145 #endif // SERIALGC
   146     default:
   147       guarantee(false, "Unrecognized perm generation");
   148         break;
   149   }
   150 }
   152 #ifndef SERIALGC
   153 // Add memory pools for ParallelScavengeHeap
   154 // This function currently only supports two generations collected heap.
   155 // The collector for ParallelScavengeHeap will have two memory managers.
   156 void MemoryService::add_parallel_scavenge_heap_info(ParallelScavengeHeap* heap) {
   157   // Two managers to keep statistics about _minor_gc_manager and _major_gc_manager GC.
   158   _minor_gc_manager = MemoryManager::get_psScavenge_memory_manager();
   159   _major_gc_manager = MemoryManager::get_psMarkSweep_memory_manager();
   160   _managers_list->append(_minor_gc_manager);
   161   _managers_list->append(_major_gc_manager);
   163   add_psYoung_memory_pool(heap->young_gen(), _major_gc_manager, _minor_gc_manager);
   164   add_psOld_memory_pool(heap->old_gen(), _major_gc_manager);
   165   add_psPerm_memory_pool(heap->perm_gen(), _major_gc_manager);
   166 }
   167 #endif // SERIALGC
   169 MemoryPool* MemoryService::add_gen(Generation* gen,
   170                                    const char* name,
   171                                    bool is_heap,
   172                                    bool support_usage_threshold) {
   174   MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
   175   GenerationPool* pool = new GenerationPool(gen, name, type, support_usage_threshold);
   176   _pools_list->append(pool);
   177   return (MemoryPool*) pool;
   178 }
   180 MemoryPool* MemoryService::add_space(ContiguousSpace* space,
   181                                      const char* name,
   182                                      bool is_heap,
   183                                      size_t max_size,
   184                                      bool support_usage_threshold) {
   185   MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
   186   ContiguousSpacePool* pool = new ContiguousSpacePool(space, name, type, max_size, support_usage_threshold);
   188   _pools_list->append(pool);
   189   return (MemoryPool*) pool;
   190 }
   192 MemoryPool* MemoryService::add_survivor_spaces(DefNewGeneration* gen,
   193                                                const char* name,
   194                                                bool is_heap,
   195                                                size_t max_size,
   196                                                bool support_usage_threshold) {
   197   MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
   198   SurvivorContiguousSpacePool* pool = new SurvivorContiguousSpacePool(gen, name, type, max_size, support_usage_threshold);
   200   _pools_list->append(pool);
   201   return (MemoryPool*) pool;
   202 }
   204 #ifndef SERIALGC
   205 MemoryPool* MemoryService::add_cms_space(CompactibleFreeListSpace* space,
   206                                          const char* name,
   207                                          bool is_heap,
   208                                          size_t max_size,
   209                                          bool support_usage_threshold) {
   210   MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
   211   CompactibleFreeListSpacePool* pool = new CompactibleFreeListSpacePool(space, name, type, max_size, support_usage_threshold);
   212   _pools_list->append(pool);
   213   return (MemoryPool*) pool;
   214 }
   215 #endif // SERIALGC
   217 // Add memory pool(s) for one generation
   218 void MemoryService::add_generation_memory_pool(Generation* gen,
   219                                                MemoryManager* major_mgr,
   220                                                MemoryManager* minor_mgr) {
   221   Generation::Name kind = gen->kind();
   222   int index = _pools_list->length();
   224   switch (kind) {
   225     case Generation::DefNew: {
   226       assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers");
   227       DefNewGeneration* young_gen = (DefNewGeneration*) gen;
   228       // Add a memory pool for each space and young gen doesn't
   229       // support low memory detection as it is expected to get filled up.
   230       MemoryPool* eden = add_space(young_gen->eden(),
   231                                    "Eden Space",
   232                                    true, /* is_heap */
   233                                    young_gen->max_eden_size(),
   234                                    false /* support_usage_threshold */);
   235       MemoryPool* survivor = add_survivor_spaces(young_gen,
   236                                                  "Survivor Space",
   237                                                  true, /* is_heap */
   238                                                  young_gen->max_survivor_size(),
   239                                                  false /* support_usage_threshold */);
   240       break;
   241     }
   243 #ifndef SERIALGC
   244     case Generation::ParNew:
   245     case Generation::ASParNew:
   246     {
   247       assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers");
   248       // Add a memory pool for each space and young gen doesn't
   249       // support low memory detection as it is expected to get filled up.
   250       ParNewGeneration* parnew_gen = (ParNewGeneration*) gen;
   251       MemoryPool* eden = add_space(parnew_gen->eden(),
   252                                    "Par Eden Space",
   253                                    true /* is_heap */,
   254                                    parnew_gen->max_eden_size(),
   255                                    false /* support_usage_threshold */);
   256       MemoryPool* survivor = add_survivor_spaces(parnew_gen,
   257                                                  "Par Survivor Space",
   258                                                  true, /* is_heap */
   259                                                  parnew_gen->max_survivor_size(),
   260                                                  false /* support_usage_threshold */);
   262       break;
   263     }
   264 #endif // SERIALGC
   266     case Generation::MarkSweepCompact: {
   267       assert(major_mgr != NULL && minor_mgr == NULL, "Should have only one manager");
   268       add_gen(gen,
   269               "Tenured Gen",
   270               true, /* is_heap */
   271               true  /* support_usage_threshold */);
   272       break;
   273     }
   275 #ifndef SERIALGC
   276     case Generation::ConcurrentMarkSweep:
   277     case Generation::ASConcurrentMarkSweep:
   278     {
   279       assert(major_mgr != NULL && minor_mgr == NULL, "Should have only one manager");
   280       ConcurrentMarkSweepGeneration* cms = (ConcurrentMarkSweepGeneration*) gen;
   281       MemoryPool* pool = add_cms_space(cms->cmsSpace(),
   282                                        "CMS Old Gen",
   283                                        true, /* is_heap */
   284                                        cms->reserved().byte_size(),
   285                                        true  /* support_usage_threshold */);
   286       break;
   287     }
   288 #endif // SERIALGC
   290     default:
   291       assert(false, "should not reach here");
   292       // no memory pool added for others
   293       break;
   294   }
   296   assert(major_mgr != NULL, "Should have at least one manager");
   297   // Link managers and the memory pools together
   298   for (int i = index; i < _pools_list->length(); i++) {
   299     MemoryPool* pool = _pools_list->at(i);
   300     major_mgr->add_pool(pool);
   301     if (minor_mgr != NULL) {
   302       minor_mgr->add_pool(pool);
   303     }
   304   }
   305 }
   307 void MemoryService::add_compact_perm_gen_memory_pool(CompactingPermGenGen* perm_gen,
   308                                                      MemoryManager* mgr) {
   309   PermanentGenerationSpec* spec = perm_gen->spec();
   310   size_t max_size = spec->max_size() - spec->read_only_size() - spec->read_write_size();
   311   MemoryPool* pool = add_space(perm_gen->unshared_space(),
   312                                "Perm Gen",
   313                                 false, /* is_heap */
   314                                 max_size,
   315                                 true   /* support_usage_threshold */);
   316   mgr->add_pool(pool);
   317   if (UseSharedSpaces) {
   318     pool = add_space(perm_gen->ro_space(),
   319                      "Perm Gen [shared-ro]",
   320                      false, /* is_heap */
   321                      spec->read_only_size(),
   322                      true   /* support_usage_threshold */);
   323     mgr->add_pool(pool);
   325     pool = add_space(perm_gen->rw_space(),
   326                      "Perm Gen [shared-rw]",
   327                      false, /* is_heap */
   328                      spec->read_write_size(),
   329                      true   /* support_usage_threshold */);
   330     mgr->add_pool(pool);
   331   }
   332 }
   334 #ifndef SERIALGC
   335 void MemoryService::add_cms_perm_gen_memory_pool(CMSPermGenGen* cms_gen,
   336                                                  MemoryManager* mgr) {
   338   MemoryPool* pool = add_cms_space(cms_gen->cmsSpace(),
   339                                    "CMS Perm Gen",
   340                                    false, /* is_heap */
   341                                    cms_gen->reserved().byte_size(),
   342                                    true   /* support_usage_threshold */);
   343   mgr->add_pool(pool);
   344 }
   346 void MemoryService::add_psYoung_memory_pool(PSYoungGen* gen, MemoryManager* major_mgr, MemoryManager* minor_mgr) {
   347   assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers");
   349   // Add a memory pool for each space and young gen doesn't
   350   // support low memory detection as it is expected to get filled up.
   351   EdenMutableSpacePool* eden = new EdenMutableSpacePool(gen,
   352                                                         gen->eden_space(),
   353                                                         "PS Eden Space",
   354                                                         MemoryPool::Heap,
   355                                                         false /* support_usage_threshold */);
   357   SurvivorMutableSpacePool* survivor = new SurvivorMutableSpacePool(gen,
   358                                                                     "PS Survivor Space",
   359                                                                     MemoryPool::Heap,
   360                                                                     false /* support_usage_threshold */);
   362   major_mgr->add_pool(eden);
   363   major_mgr->add_pool(survivor);
   364   minor_mgr->add_pool(eden);
   365   minor_mgr->add_pool(survivor);
   366   _pools_list->append(eden);
   367   _pools_list->append(survivor);
   368 }
   370 void MemoryService::add_psOld_memory_pool(PSOldGen* gen, MemoryManager* mgr) {
   371   PSGenerationPool* old_gen = new PSGenerationPool(gen,
   372                                                    "PS Old Gen",
   373                                                    MemoryPool::Heap,
   374                                                    true /* support_usage_threshold */);
   375   mgr->add_pool(old_gen);
   376   _pools_list->append(old_gen);
   377 }
   379 void MemoryService::add_psPerm_memory_pool(PSPermGen* gen, MemoryManager* mgr) {
   380   PSGenerationPool* perm_gen = new PSGenerationPool(gen,
   381                                                     "PS Perm Gen",
   382                                                     MemoryPool::NonHeap,
   383                                                     true /* support_usage_threshold */);
   384   mgr->add_pool(perm_gen);
   385   _pools_list->append(perm_gen);
   386 }
   387 #endif // SERIALGC
   389 void MemoryService::add_code_heap_memory_pool(CodeHeap* heap) {
   390   _code_heap_pool = new CodeHeapPool(heap,
   391                                      "Code Cache",
   392                                      true /* support_usage_threshold */);
   393   MemoryManager* mgr = MemoryManager::get_code_cache_memory_manager();
   394   mgr->add_pool(_code_heap_pool);
   396   _pools_list->append(_code_heap_pool);
   397   _managers_list->append(mgr);
   398 }
   400 MemoryManager* MemoryService::get_memory_manager(instanceHandle mh) {
   401   for (int i = 0; i < _managers_list->length(); i++) {
   402     MemoryManager* mgr = _managers_list->at(i);
   403     if (mgr->is_manager(mh)) {
   404       return mgr;
   405     }
   406   }
   407   return NULL;
   408 }
   410 MemoryPool* MemoryService::get_memory_pool(instanceHandle ph) {
   411   for (int i = 0; i < _pools_list->length(); i++) {
   412     MemoryPool* pool = _pools_list->at(i);
   413     if (pool->is_pool(ph)) {
   414       return pool;
   415     }
   416   }
   417   return NULL;
   418 }
   420 void MemoryService::track_memory_usage() {
   421   // Track the peak memory usage
   422   for (int i = 0; i < _pools_list->length(); i++) {
   423     MemoryPool* pool = _pools_list->at(i);
   424     pool->record_peak_memory_usage();
   425   }
   427   // Detect low memory
   428   LowMemoryDetector::detect_low_memory();
   429 }
   431 void MemoryService::track_memory_pool_usage(MemoryPool* pool) {
   432   // Track the peak memory usage
   433   pool->record_peak_memory_usage();
   435   // Detect low memory
   436   if (LowMemoryDetector::is_enabled(pool)) {
   437     LowMemoryDetector::detect_low_memory(pool);
   438   }
   439 }
   441 void MemoryService::gc_begin(bool fullGC) {
   442   GCMemoryManager* mgr;
   443   if (fullGC) {
   444     mgr = _major_gc_manager;
   445   } else {
   446     mgr = _minor_gc_manager;
   447   }
   448   assert(mgr->is_gc_memory_manager(), "Sanity check");
   449   mgr->gc_begin();
   451   // Track the peak memory usage when GC begins
   452   for (int i = 0; i < _pools_list->length(); i++) {
   453     MemoryPool* pool = _pools_list->at(i);
   454     pool->record_peak_memory_usage();
   455   }
   456 }
   458 void MemoryService::gc_end(bool fullGC) {
   459   GCMemoryManager* mgr;
   460   if (fullGC) {
   461     mgr = (GCMemoryManager*) _major_gc_manager;
   462   } else {
   463     mgr = (GCMemoryManager*) _minor_gc_manager;
   464   }
   465   assert(mgr->is_gc_memory_manager(), "Sanity check");
   467   // register the GC end statistics and memory usage
   468   mgr->gc_end();
   469 }
   471 void MemoryService::oops_do(OopClosure* f) {
   472   int i;
   474   for (i = 0; i < _pools_list->length(); i++) {
   475     MemoryPool* pool = _pools_list->at(i);
   476     pool->oops_do(f);
   477   }
   478   for (i = 0; i < _managers_list->length(); i++) {
   479     MemoryManager* mgr = _managers_list->at(i);
   480     mgr->oops_do(f);
   481   }
   482 }
   484 bool MemoryService::set_verbose(bool verbose) {
   485   MutexLocker m(Management_lock);
   486   // verbose will be set to the previous value
   487   bool succeed = CommandLineFlags::boolAtPut((char*)"PrintGC", &verbose, MANAGEMENT);
   488   assert(succeed, "Setting PrintGC flag fails");
   489   ClassLoadingService::reset_trace_class_unloading();
   491   return verbose;
   492 }
   494 Handle MemoryService::create_MemoryUsage_obj(MemoryUsage usage, TRAPS) {
   495   klassOop k = Management::java_lang_management_MemoryUsage_klass(CHECK_NH);
   496   instanceKlassHandle ik(THREAD, k);
   498   instanceHandle obj = ik->allocate_instance_handle(CHECK_NH);
   500   JavaValue result(T_VOID);
   501   JavaCallArguments args(10);
   502   args.push_oop(obj);                         // receiver
   503   args.push_long(usage.init_size_as_jlong()); // Argument 1
   504   args.push_long(usage.used_as_jlong());      // Argument 2
   505   args.push_long(usage.committed_as_jlong()); // Argument 3
   506   args.push_long(usage.max_size_as_jlong());  // Argument 4
   508   JavaCalls::call_special(&result,
   509                           ik,
   510                           vmSymbolHandles::object_initializer_name(),
   511                           vmSymbolHandles::long_long_long_long_void_signature(),
   512                           &args,
   513                           CHECK_NH);
   514   return obj;
   515 }
   516 //
   517 // GC manager type depends on the type of Generation. Depending the space
   518 // availablity and vm option the gc uses major gc manager or minor gc
   519 // manager or both. The type of gc manager depends on the generation kind.
   520 // For DefNew, ParNew and ASParNew generation doing scavange gc uses minor
   521 // gc manager (so _fullGC is set to false ) and for other generation kind
   522 // DOing mark-sweep-compact uses major gc manager (so _fullGC is set
   523 // to true).
   524 TraceMemoryManagerStats::TraceMemoryManagerStats(Generation::Name kind) {
   525   switch (kind) {
   526     case Generation::DefNew:
   527 #ifndef SERIALGC
   528     case Generation::ParNew:
   529     case Generation::ASParNew:
   530 #endif // SERIALGC
   531       _fullGC=false;
   532       break;
   533     case Generation::MarkSweepCompact:
   534 #ifndef SERIALGC
   535     case Generation::ConcurrentMarkSweep:
   536     case Generation::ASConcurrentMarkSweep:
   537 #endif // SERIALGC
   538       _fullGC=true;
   539       break;
   540     default:
   541       assert(false, "Unrecognized gc generation kind.");
   542   }
   543   MemoryService::gc_begin(_fullGC);
   544 }
   545 TraceMemoryManagerStats::TraceMemoryManagerStats(bool fullGC) {
   546   _fullGC = fullGC;
   547   MemoryService::gc_begin(_fullGC);
   548 }
   550 TraceMemoryManagerStats::~TraceMemoryManagerStats() {
   551   MemoryService::gc_end(_fullGC);
   552 }

mercurial