void GCNotifier::pushNotification(GCMemoryManager *mgr, constchar *action, constchar *cause) { // Make a copy of the last GC statistics // GC may occur between now and the creation of the notification int num_pools = MemoryService::num_memory_pools(); // stat is deallocated inside GCNotificationRequest
GCStatInfo* stat = new GCStatInfo(num_pools);
mgr->get_last_gc_stat(stat); // timestamp is current time in ms
GCNotificationRequest *request = new GCNotificationRequest(os::javaTimeMillis(),mgr,action,cause,stat);
addRequest(request);
}
// The array allocations below should use a handle containing mu_klass // as the first allocation could trigger a GC, causing the actual // klass oop to move, and leaving mu_klass pointing to the old // location.
objArrayOop bu = oopFactory::new_objArray(mu_klass, MemoryService::num_memory_pools(), CHECK_NH);
objArrayHandle usage_before_gc_ah(THREAD, bu);
objArrayOop au = oopFactory::new_objArray(mu_klass, MemoryService::num_memory_pools(), CHECK_NH);
objArrayHandle usage_after_gc_ah(THREAD, au);
for (int i = 0; i < MemoryService::num_memory_pools(); i++) {
Handle before_usage = MemoryService::create_MemoryUsage_obj(gcStatInfo->before_gc_usage_for_pool(i), CHECK_NH);
Handle after_usage;
MemoryUsage u = gcStatInfo->after_gc_usage_for_pool(i); if (u.max_size() == 0 && u.used() > 0) { // If max size == 0, this pool is a survivor space. // Set max size = -1 since the pools will be swapped after GC.
MemoryUsage usage(u.init_size(), u.used(), u.committed(), (size_t)-1);
after_usage = MemoryService::create_MemoryUsage_obj(usage, CHECK_NH);
} else {
after_usage = MemoryService::create_MemoryUsage_obj(u, CHECK_NH);
}
usage_before_gc_ah->obj_at_put(i, before_usage());
usage_after_gc_ah->obj_at_put(i, after_usage());
}
// Current implementation only has 1 attribute (number of GC threads) // The type is 'I'
objArrayOop extra_args_array = oopFactory::new_objArray(vmClasses::Integer_klass(), 1, CHECK_NH);
objArrayHandle extra_array (THREAD, extra_args_array);
void GCNotifier::sendNotification(TRAPS) {
GCNotifier::sendNotificationInternal(THREAD); // Clearing pending exception to avoid premature termination of // the service thread if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
}
}
class NotificationMark : public StackObj { // This class is used in GCNotifier::sendNotificationInternal to ensure that // the GCNotificationRequest object is properly cleaned up, whatever path // is used to exit the method.
GCNotificationRequest* _request; public:
NotificationMark(GCNotificationRequest* r) {
_request = r;
}
~NotificationMark() {
assert(_request != NULL, "Sanity check"); delete _request;
}
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.