< prev index next >

src/hotspot/share/memory/heapInspection.hpp

Print this page
rev 58082 : 8214535: Parallel heap inspection for jmap histo (G1)
Summary: Add parallel heap inspection to speedup jmap -histo, this patch support G1
Reviewed-by:
Contributed-by: lzang


  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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_MEMORY_HEAPINSPECTION_HPP
  26 #define SHARE_MEMORY_HEAPINSPECTION_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "oops/objArrayOop.hpp"
  30 #include "oops/oop.hpp"
  31 #include "oops/annotations.hpp"
  32 #include "utilities/macros.hpp"
  33 
  34 #if INCLUDE_SERVICES
  35 
  36 
  37 // HeapInspection
  38 
  39 // KlassInfoTable is a bucket hash table that
  40 // maps Klass*s to extra information:
  41 //    instance count and instance word size.
  42 //
  43 // A KlassInfoBucket is the head of a link list
  44 // of KlassInfoEntry's
  45 //
  46 // KlassInfoHisto is a growable array of pointers
  47 // to KlassInfoEntry's and is used to sort
  48 // the entries.
  49 
  50 class KlassInfoEntry: public CHeapObj<mtInternal> {
  51  private:
  52   KlassInfoEntry* _next;
  53   Klass*          _klass;


 105   size_t _size_of_instances_in_words;
 106 
 107   // An aligned reference address (typically the least
 108   // address in the perm gen) used for hashing klass
 109   // objects.
 110   HeapWord* _ref;
 111 
 112   KlassInfoBucket* _buckets;
 113   uint hash(const Klass* p);
 114   KlassInfoEntry* lookup(Klass* k); // allocates if not found!
 115 
 116   class AllClassesFinder;
 117 
 118  public:
 119   KlassInfoTable(bool add_all_classes);
 120   ~KlassInfoTable();
 121   bool record_instance(const oop obj);
 122   void iterate(KlassInfoClosure* cic);
 123   bool allocation_failed() { return _buckets == NULL; }
 124   size_t size_of_instances_in_words() const;


 125 
 126   friend class KlassInfoHisto;
 127   friend class KlassHierarchy;
 128 };
 129 
 130 class KlassHierarchy : AllStatic {
 131  public:
 132   static void print_class_hierarchy(outputStream* st, bool print_interfaces,  bool print_subclasses,
 133                                     char* classname);
 134 
 135  private:
 136   static void set_do_print_for_class_hierarchy(KlassInfoEntry* cie, KlassInfoTable* cit,
 137                                                bool print_subclasse);
 138   static void print_class(outputStream* st, KlassInfoEntry* cie, bool print_subclasses);
 139 };
 140 
 141 class KlassInfoHisto : public StackObj {
 142  private:
 143   static const int _histo_initial_size = 1000;
 144   KlassInfoTable *_cit;


 194     return w + 1;
 195   }
 196 
 197  public:
 198   KlassInfoHisto(KlassInfoTable* cit);
 199   ~KlassInfoHisto();
 200   void add(KlassInfoEntry* cie);
 201   void print_histo_on(outputStream* st);
 202   void sort();
 203 };
 204 
 205 #endif // INCLUDE_SERVICES
 206 
 207 // These declarations are needed since the declaration of KlassInfoTable and
 208 // KlassInfoClosure are guarded by #if INLCUDE_SERVICES
 209 class KlassInfoTable;
 210 class KlassInfoClosure;
 211 
 212 class HeapInspection : public StackObj {
 213  public:
 214   void heap_inspection(outputStream* st) NOT_SERVICES_RETURN;
 215   size_t populate_table(KlassInfoTable* cit, BoolObjectClosure* filter = NULL) NOT_SERVICES_RETURN_(0);
 216   static void find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) NOT_SERVICES_RETURN;
 217  private:
 218   void iterate_over_heap(KlassInfoTable* cit, BoolObjectClosure* filter = NULL);
 219 };




































 220 
 221 #endif // SHARE_MEMORY_HEAPINSPECTION_HPP


  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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_MEMORY_HEAPINSPECTION_HPP
  26 #define SHARE_MEMORY_HEAPINSPECTION_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "oops/objArrayOop.hpp"
  30 #include "oops/oop.hpp"
  31 #include "oops/annotations.hpp"
  32 #include "utilities/macros.hpp"
  33 #include "gc/shared/workgroup.hpp"
  34 #if INCLUDE_SERVICES
  35 
  36 
  37 // HeapInspection
  38 
  39 // KlassInfoTable is a bucket hash table that
  40 // maps Klass*s to extra information:
  41 //    instance count and instance word size.
  42 //
  43 // A KlassInfoBucket is the head of a link list
  44 // of KlassInfoEntry's
  45 //
  46 // KlassInfoHisto is a growable array of pointers
  47 // to KlassInfoEntry's and is used to sort
  48 // the entries.
  49 
  50 class KlassInfoEntry: public CHeapObj<mtInternal> {
  51  private:
  52   KlassInfoEntry* _next;
  53   Klass*          _klass;


 105   size_t _size_of_instances_in_words;
 106 
 107   // An aligned reference address (typically the least
 108   // address in the perm gen) used for hashing klass
 109   // objects.
 110   HeapWord* _ref;
 111 
 112   KlassInfoBucket* _buckets;
 113   uint hash(const Klass* p);
 114   KlassInfoEntry* lookup(Klass* k); // allocates if not found!
 115 
 116   class AllClassesFinder;
 117 
 118  public:
 119   KlassInfoTable(bool add_all_classes);
 120   ~KlassInfoTable();
 121   bool record_instance(const oop obj);
 122   void iterate(KlassInfoClosure* cic);
 123   bool allocation_failed() { return _buckets == NULL; }
 124   size_t size_of_instances_in_words() const;
 125   bool merge(KlassInfoTable* table);
 126   bool merge_entry(const KlassInfoEntry* cie);
 127 
 128   friend class KlassInfoHisto;
 129   friend class KlassHierarchy;
 130 };
 131 
 132 class KlassHierarchy : AllStatic {
 133  public:
 134   static void print_class_hierarchy(outputStream* st, bool print_interfaces,  bool print_subclasses,
 135                                     char* classname);
 136 
 137  private:
 138   static void set_do_print_for_class_hierarchy(KlassInfoEntry* cie, KlassInfoTable* cit,
 139                                                bool print_subclasse);
 140   static void print_class(outputStream* st, KlassInfoEntry* cie, bool print_subclasses);
 141 };
 142 
 143 class KlassInfoHisto : public StackObj {
 144  private:
 145   static const int _histo_initial_size = 1000;
 146   KlassInfoTable *_cit;


 196     return w + 1;
 197   }
 198 
 199  public:
 200   KlassInfoHisto(KlassInfoTable* cit);
 201   ~KlassInfoHisto();
 202   void add(KlassInfoEntry* cie);
 203   void print_histo_on(outputStream* st);
 204   void sort();
 205 };
 206 
 207 #endif // INCLUDE_SERVICES
 208 
 209 // These declarations are needed since the declaration of KlassInfoTable and
 210 // KlassInfoClosure are guarded by #if INLCUDE_SERVICES
 211 class KlassInfoTable;
 212 class KlassInfoClosure;
 213 
 214 class HeapInspection : public StackObj {
 215  public:
 216   void heap_inspection(outputStream* st, size_t parallel_thread_num = 1) NOT_SERVICES_RETURN;
 217   size_t populate_table(KlassInfoTable* cit, BoolObjectClosure* filter = NULL, size_t parallel_thread_num = 1) NOT_SERVICES_RETURN_(0);
 218   static void find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) NOT_SERVICES_RETURN;
 219  private:
 220   void iterate_over_heap(KlassInfoTable* cit, BoolObjectClosure* filter = NULL);
 221 };
 222 
 223 class ParHeapInspectTask : public AbstractGangTask {
 224  private:
 225   CollectedHeap* _heap;
 226   KlassInfoTable* _shared_cit;
 227   BoolObjectClosure* _filter;
 228   size_t* _shared_missed_count;
 229   bool _success;
 230   Mutex _mutex;
 231   size_t _par_thread_num;
 232 
 233  public:
 234   ParHeapInspectTask(CollectedHeap* heap, KlassInfoTable* shared_cit,
 235                      BoolObjectClosure* filter, size_t* shared_missed_count,
 236                      size_t parallel_thread_num) :
 237       AbstractGangTask("Iterating heap"),
 238       _heap(heap),
 239       _shared_cit(shared_cit),
 240       _filter(filter),
 241       _shared_missed_count(shared_missed_count),
 242       _success(true),
 243       _mutex(Mutex::leaf, "Parallel heap iteration data merge lock"),
 244       _par_thread_num(parallel_thread_num) { }
 245 
 246   bool is_success() {
 247     return _success;
 248   }
 249 
 250   CollectedHeap* getHeap() {
 251     return _heap;
 252   }
 253   virtual void work(uint worker_id);
 254   virtual void do_object_iterate_parallel(ObjectClosure* closure, uint worker_id) = 0;
 255 };
 256 
 257 
 258 
 259 #endif // SHARE_MEMORY_HEAPINSPECTION_HPP
< prev index next >