Print this page
rev 6875 : 8056240: Investigate increased GC remark time after class unloading changes in CRM Fuse
Reviewed-by: mgerdin, coleenp, bdelsart

Split Split Close
Expand all
Collapse all
          --- old/src/share/vm/classfile/classLoaderData.cpp
          +++ new/src/share/vm/classfile/classLoaderData.cpp
↓ open down ↓ 739 lines elided ↑ open up ↑
 740  740      }
 741  741    }
 742  742  
 743  743    return false;
 744  744  }
 745  745  #endif // PRODUCT
 746  746  
 747  747  
 748  748  // Move class loader data from main list to the unloaded list for unloading
 749  749  // and deallocation later.
 750      -bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) {
      750 +bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure, bool clean_alive) {
 751  751    ClassLoaderData* data = _head;
 752  752    ClassLoaderData* prev = NULL;
 753  753    bool seen_dead_loader = false;
 754  754  
 755  755    // Save previous _unloading pointer for CMS which may add to unloading list before
 756  756    // purging and we don't want to rewalk the previously unloaded class loader data.
 757  757    _saved_unloading = _unloading;
 758  758  
 759      -  // mark metadata seen on the stack and code cache so we can delete
 760      -  // unneeded entries.
 761      -  bool has_redefined_a_class = JvmtiExport::has_redefined_a_class();
 762      -  MetadataOnStackMark md_on_stack;
 763  759    while (data != NULL) {
 764  760      if (data->is_alive(is_alive_closure)) {
 765      -      if (has_redefined_a_class) {
 766      -        data->classes_do(InstanceKlass::purge_previous_versions);
 767      -      }
 768      -      data->free_deallocate_list();
 769  761        prev = data;
 770  762        data = data->next();
 771  763        continue;
 772  764      }
 773  765      seen_dead_loader = true;
 774  766      ClassLoaderData* dead = data;
 775  767      dead->unload();
 776  768      data = data->next();
 777  769      // Remove from loader list.
 778  770      // This class loader data will no longer be found
↓ open down ↓ 1 lines elided ↑ open up ↑
 780  772      if (prev != NULL) {
 781  773        prev->set_next(data);
 782  774      } else {
 783  775        assert(dead == _head, "sanity check");
 784  776        _head = data;
 785  777      }
 786  778      dead->set_next(_unloading);
 787  779      _unloading = dead;
 788  780    }
 789  781  
      782 +  if (clean_alive) {
      783 +    // Clean previous versions and the deallocate list.
      784 +    ClassLoaderDataGraph::clean_metaspaces();
      785 +  }
      786 +
 790  787    if (seen_dead_loader) {
 791  788      post_class_unload_events();
 792  789    }
 793  790  
 794  791    return seen_dead_loader;
 795  792  }
 796  793  
      794 +void ClassLoaderDataGraph::clean_metaspaces() {
      795 +  // mark metadata seen on the stack and code cache so we can delete unneeded entries.
      796 +  bool has_redefined_a_class = JvmtiExport::has_redefined_a_class();
      797 +  MetadataOnStackMark md_on_stack(has_redefined_a_class);
      798 +
      799 +  if (has_redefined_a_class) {
      800 +    // purge_previous_versions also cleans weak method links. Because
      801 +    // one method's MDO can reference another method from another
      802 +    // class loader, we need to first clean weak method links for all
      803 +    // class loaders here. Below, we can then free redefined methods
      804 +    // for all class loaders.
      805 +    for (ClassLoaderData* data = _head; data != NULL; data = data->next()) {
      806 +      data->classes_do(InstanceKlass::purge_previous_versions);
      807 +    }
      808 +  }
      809 +
      810 +  // Need to purge the previous version before deallocating.
      811 +  free_deallocate_lists();
      812 +}
      813 +
 797  814  void ClassLoaderDataGraph::purge() {
 798  815    assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
 799  816    ClassLoaderData* list = _unloading;
 800  817    _unloading = NULL;
 801  818    ClassLoaderData* next = list;
 802  819    while (next != NULL) {
 803  820      ClassLoaderData* purge_me = next;
 804  821      next = purge_me->next();
 805  822      delete purge_me;
 806  823    }
↓ open down ↓ 7 lines elided ↑ open up ↑
 814  831      if (Tracing::is_event_enabled(TraceClassUnloadEvent)) {
 815  832        assert(_unloading != NULL, "need class loader data unload list!");
 816  833        _class_unload_time = Ticks::now();
 817  834        classes_unloading_do(&class_unload_event);
 818  835      }
 819  836      Tracing::on_unloading_classes();
 820  837    }
 821  838  #endif
 822  839  }
 823  840  
      841 +void ClassLoaderDataGraph::free_deallocate_lists() {
      842 +  for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
      843 +    // We need to keep this data until InstanceKlass::purge_previous_version has been
      844 +    // called on all alive classes. See the comment in ClassLoaderDataGraph::clean_metaspaces.
      845 +    cld->free_deallocate_list();
      846 +  }
      847 +}
      848 +
 824  849  // CDS support
 825  850  
 826  851  // Global metaspaces for writing information to the shared archive.  When
 827  852  // application CDS is supported, we may need one per metaspace, so this
 828  853  // sort of looks like it.
 829  854  Metaspace* ClassLoaderData::_ro_metaspace = NULL;
 830  855  Metaspace* ClassLoaderData::_rw_metaspace = NULL;
 831  856  static bool _shared_metaspaces_initialized = false;
 832  857  
 833  858  // Initialize shared metaspaces (change to call from somewhere not lazily)
↓ open down ↓ 129 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX