65 _usage_threshold = new ThresholdSupport(support_usage_threshold, support_usage_threshold); 66 // gc usage threshold supports only high threshold 67 _gc_usage_threshold = new ThresholdSupport(support_gc_threshold, support_gc_threshold); 68 } 69 70 void MemoryPool::add_manager(MemoryManager* mgr) { 71 assert(_num_managers < MemoryPool::max_num_managers, "_num_managers exceeds the max"); 72 if (_num_managers < MemoryPool::max_num_managers) { 73 _managers[_num_managers] = mgr; 74 _num_managers++; 75 } 76 } 77 78 79 // Returns an instanceHandle of a MemoryPool object. 80 // It creates a MemoryPool instance when the first time 81 // this function is called. 82 instanceOop MemoryPool::get_memory_pool_instance(TRAPS) { 83 // Must do an acquire so as to force ordering of subsequent 84 // loads from anything _memory_pool_obj points to or implies. 85 instanceOop pool_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_pool_obj); 86 if (pool_obj == NULL) { 87 // It's ok for more than one thread to execute the code up to the locked region. 88 // Extra pool instances will just be gc'ed. 89 InstanceKlass* ik = Management::sun_management_ManagementFactoryHelper_klass(CHECK_NULL); 90 91 Handle pool_name = java_lang_String::create_from_str(_name, CHECK_NULL); 92 jlong usage_threshold_value = (_usage_threshold->is_high_threshold_supported() ? 0 : -1L); 93 jlong gc_usage_threshold_value = (_gc_usage_threshold->is_high_threshold_supported() ? 0 : -1L); 94 95 JavaValue result(T_OBJECT); 96 JavaCallArguments args; 97 args.push_oop(pool_name); // Argument 1 98 args.push_int((int) is_heap()); // Argument 2 99 100 Symbol* method_name = vmSymbols::createMemoryPool_name(); 101 Symbol* signature = vmSymbols::createMemoryPool_signature(); 102 103 args.push_long(usage_threshold_value); // Argument 3 104 args.push_long(gc_usage_threshold_value); // Argument 4 105 106 JavaCalls::call_static(&result, 107 ik, 108 method_name, 109 signature, 110 &args, 111 CHECK_NULL); 112 113 instanceOop p = (instanceOop) result.get_jobject(); 114 instanceHandle pool(THREAD, p); 115 116 { 117 // Get lock since another thread may have create the instance 118 MutexLocker ml(Management_lock); 119 120 // Check if another thread has created the pool. We reload 121 // _memory_pool_obj here because some other thread may have 122 // initialized it while we were executing the code before the lock. 123 // 124 // The lock has done an acquire, so the load can't float above it, 125 // but we need to do a load_acquire as above. 126 pool_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_pool_obj); 127 if (pool_obj != NULL) { 128 return pool_obj; 129 } 130 131 // Get the address of the object we created via call_special. 132 pool_obj = pool(); 133 134 // Use store barrier to make sure the memory accesses associated 135 // with creating the pool are visible before publishing its address. 136 // The unlock will publish the store to _memory_pool_obj because 137 // it does a release first. 138 OrderAccess::release_store_ptr(&_memory_pool_obj, pool_obj); 139 } 140 } 141 142 return pool_obj; 143 } 144 145 inline static size_t get_max_value(size_t val1, size_t val2) { 146 return (val1 > val2 ? val1 : val2); 147 } 148 149 void MemoryPool::record_peak_memory_usage() { 150 // Caller in JDK is responsible for synchronization - 151 // acquire the lock for this memory pool before calling VM 152 MemoryUsage usage = get_memory_usage(); 153 size_t peak_used = get_max_value(usage.used(), _peak_usage.used()); 154 size_t peak_committed = get_max_value(usage.committed(), _peak_usage.committed()); 155 size_t peak_max_size = get_max_value(usage.max_size(), _peak_usage.max_size()); 156 157 _peak_usage = MemoryUsage(initial_size(), peak_used, peak_committed, peak_max_size); 158 } | 65 _usage_threshold = new ThresholdSupport(support_usage_threshold, support_usage_threshold); 66 // gc usage threshold supports only high threshold 67 _gc_usage_threshold = new ThresholdSupport(support_gc_threshold, support_gc_threshold); 68 } 69 70 void MemoryPool::add_manager(MemoryManager* mgr) { 71 assert(_num_managers < MemoryPool::max_num_managers, "_num_managers exceeds the max"); 72 if (_num_managers < MemoryPool::max_num_managers) { 73 _managers[_num_managers] = mgr; 74 _num_managers++; 75 } 76 } 77 78 79 // Returns an instanceHandle of a MemoryPool object. 80 // It creates a MemoryPool instance when the first time 81 // this function is called. 82 instanceOop MemoryPool::get_memory_pool_instance(TRAPS) { 83 // Must do an acquire so as to force ordering of subsequent 84 // loads from anything _memory_pool_obj points to or implies. 85 instanceOop pool_obj = OrderAccess::load_acquire(&_memory_pool_obj); 86 if (pool_obj == NULL) { 87 // It's ok for more than one thread to execute the code up to the locked region. 88 // Extra pool instances will just be gc'ed. 89 InstanceKlass* ik = Management::sun_management_ManagementFactoryHelper_klass(CHECK_NULL); 90 91 Handle pool_name = java_lang_String::create_from_str(_name, CHECK_NULL); 92 jlong usage_threshold_value = (_usage_threshold->is_high_threshold_supported() ? 0 : -1L); 93 jlong gc_usage_threshold_value = (_gc_usage_threshold->is_high_threshold_supported() ? 0 : -1L); 94 95 JavaValue result(T_OBJECT); 96 JavaCallArguments args; 97 args.push_oop(pool_name); // Argument 1 98 args.push_int((int) is_heap()); // Argument 2 99 100 Symbol* method_name = vmSymbols::createMemoryPool_name(); 101 Symbol* signature = vmSymbols::createMemoryPool_signature(); 102 103 args.push_long(usage_threshold_value); // Argument 3 104 args.push_long(gc_usage_threshold_value); // Argument 4 105 106 JavaCalls::call_static(&result, 107 ik, 108 method_name, 109 signature, 110 &args, 111 CHECK_NULL); 112 113 instanceOop p = (instanceOop) result.get_jobject(); 114 instanceHandle pool(THREAD, p); 115 116 { 117 // Get lock since another thread may have create the instance 118 MutexLocker ml(Management_lock); 119 120 // Check if another thread has created the pool. We reload 121 // _memory_pool_obj here because some other thread may have 122 // initialized it while we were executing the code before the lock. 123 // 124 // The lock has done an acquire, so the load can't float above it, 125 // but we need to do a load_acquire as above. 126 pool_obj = OrderAccess::load_acquire(&_memory_pool_obj); 127 if (pool_obj != NULL) { 128 return pool_obj; 129 } 130 131 // Get the address of the object we created via call_special. 132 pool_obj = pool(); 133 134 // Use store barrier to make sure the memory accesses associated 135 // with creating the pool are visible before publishing its address. 136 // The unlock will publish the store to _memory_pool_obj because 137 // it does a release first. 138 OrderAccess::release_store(&_memory_pool_obj, pool_obj); 139 } 140 } 141 142 return pool_obj; 143 } 144 145 inline static size_t get_max_value(size_t val1, size_t val2) { 146 return (val1 > val2 ? val1 : val2); 147 } 148 149 void MemoryPool::record_peak_memory_usage() { 150 // Caller in JDK is responsible for synchronization - 151 // acquire the lock for this memory pool before calling VM 152 MemoryUsage usage = get_memory_usage(); 153 size_t peak_used = get_max_value(usage.used(), _peak_usage.used()); 154 size_t peak_committed = get_max_value(usage.committed(), _peak_usage.committed()); 155 size_t peak_max_size = get_max_value(usage.max_size(), _peak_usage.max_size()); 156 157 _peak_usage = MemoryUsage(initial_size(), peak_used, peak_committed, peak_max_size); 158 } |