8011218: Kitchensink hanged, likely NMT is to blame
Made NMT query safepoint aware. Reviewed-by: dholmes, coleenp
This commit is contained in:
parent
d567edd809
commit
3a817dc8b4
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,9 +23,12 @@
|
|||||||
*/
|
*/
|
||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "memory/allocation.hpp"
|
#include "memory/allocation.hpp"
|
||||||
|
#include "runtime/safepoint.hpp"
|
||||||
|
#include "runtime/thread.inline.hpp"
|
||||||
#include "services/memBaseline.hpp"
|
#include "services/memBaseline.hpp"
|
||||||
#include "services/memTracker.hpp"
|
#include "services/memTracker.hpp"
|
||||||
|
|
||||||
|
|
||||||
MemType2Name MemBaseline::MemType2NameMap[NUMBER_OF_MEMORY_TYPE] = {
|
MemType2Name MemBaseline::MemType2NameMap[NUMBER_OF_MEMORY_TYPE] = {
|
||||||
{mtJavaHeap, "Java Heap"},
|
{mtJavaHeap, "Java Heap"},
|
||||||
{mtClass, "Class"},
|
{mtClass, "Class"},
|
||||||
@ -149,6 +152,14 @@ bool MemBaseline::baseline_malloc_summary(const MemPointerArray* malloc_records)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if there is a safepoint in progress, if so, block the thread
|
||||||
|
// for the safepoint
|
||||||
|
void MemBaseline::check_safepoint(JavaThread* thr) {
|
||||||
|
if (SafepointSynchronize::is_synchronizing()) {
|
||||||
|
SafepointSynchronize::block(thr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// baseline mmap'd memory records, generate overall summary and summaries by
|
// baseline mmap'd memory records, generate overall summary and summaries by
|
||||||
// memory types
|
// memory types
|
||||||
bool MemBaseline::baseline_vm_summary(const MemPointerArray* vm_records) {
|
bool MemBaseline::baseline_vm_summary(const MemPointerArray* vm_records) {
|
||||||
@ -306,7 +317,7 @@ bool MemBaseline::baseline_vm_details(const MemPointerArray* vm_records) {
|
|||||||
committed_rec->pc() != vm_ptr->pc()) {
|
committed_rec->pc() != vm_ptr->pc()) {
|
||||||
if (!_vm_map->append(vm_ptr)) {
|
if (!_vm_map->append(vm_ptr)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
committed_rec = (VMMemRegionEx*)_vm_map->at(_vm_map->length() - 1);
|
committed_rec = (VMMemRegionEx*)_vm_map->at(_vm_map->length() - 1);
|
||||||
} else {
|
} else {
|
||||||
committed_rec->expand_region(vm_ptr->addr(), vm_ptr->size());
|
committed_rec->expand_region(vm_ptr->addr(), vm_ptr->size());
|
||||||
@ -344,16 +355,27 @@ bool MemBaseline::baseline_vm_details(const MemPointerArray* vm_records) {
|
|||||||
|
|
||||||
// baseline a snapshot. If summary_only = false, memory usages aggregated by
|
// baseline a snapshot. If summary_only = false, memory usages aggregated by
|
||||||
// callsites are also baselined.
|
// callsites are also baselined.
|
||||||
|
// The method call can be lengthy, especially when detail tracking info is
|
||||||
|
// requested. So the method checks for safepoint explicitly.
|
||||||
bool MemBaseline::baseline(MemSnapshot& snapshot, bool summary_only) {
|
bool MemBaseline::baseline(MemSnapshot& snapshot, bool summary_only) {
|
||||||
MutexLockerEx snapshot_locker(snapshot._lock, true);
|
Thread* THREAD = Thread::current();
|
||||||
|
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
||||||
|
MutexLocker snapshot_locker(snapshot._lock);
|
||||||
reset();
|
reset();
|
||||||
_baselined = baseline_malloc_summary(snapshot._alloc_ptrs) &&
|
_baselined = baseline_malloc_summary(snapshot._alloc_ptrs);
|
||||||
baseline_vm_summary(snapshot._vm_ptrs);
|
if (_baselined) {
|
||||||
|
check_safepoint((JavaThread*)THREAD);
|
||||||
|
_baselined = baseline_vm_summary(snapshot._vm_ptrs);
|
||||||
|
}
|
||||||
_number_of_classes = snapshot.number_of_classes();
|
_number_of_classes = snapshot.number_of_classes();
|
||||||
|
|
||||||
if (!summary_only && MemTracker::track_callsite() && _baselined) {
|
if (!summary_only && MemTracker::track_callsite() && _baselined) {
|
||||||
_baselined = baseline_malloc_details(snapshot._alloc_ptrs) &&
|
check_safepoint((JavaThread*)THREAD);
|
||||||
baseline_vm_details(snapshot._vm_ptrs);
|
_baselined = baseline_malloc_details(snapshot._alloc_ptrs);
|
||||||
|
if (_baselined) {
|
||||||
|
check_safepoint((JavaThread*)THREAD);
|
||||||
|
_baselined = baseline_vm_details(snapshot._vm_ptrs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return _baselined;
|
return _baselined;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -330,6 +330,9 @@ class MemBaseline VALUE_OBJ_CLASS_SPEC {
|
|||||||
// should not use copy constructor
|
// should not use copy constructor
|
||||||
MemBaseline(MemBaseline& copy) { ShouldNotReachHere(); }
|
MemBaseline(MemBaseline& copy) { ShouldNotReachHere(); }
|
||||||
|
|
||||||
|
// check and block at a safepoint
|
||||||
|
static inline void check_safepoint(JavaThread* thr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// create a memory baseline
|
// create a memory baseline
|
||||||
MemBaseline();
|
MemBaseline();
|
||||||
|
@ -573,7 +573,7 @@ void MemTracker::thread_exiting(JavaThread* thread) {
|
|||||||
|
|
||||||
// baseline current memory snapshot
|
// baseline current memory snapshot
|
||||||
bool MemTracker::baseline() {
|
bool MemTracker::baseline() {
|
||||||
MutexLockerEx lock(_query_lock, true);
|
MutexLocker lock(_query_lock);
|
||||||
MemSnapshot* snapshot = get_snapshot();
|
MemSnapshot* snapshot = get_snapshot();
|
||||||
if (snapshot != NULL) {
|
if (snapshot != NULL) {
|
||||||
return _baseline.baseline(*snapshot, false);
|
return _baseline.baseline(*snapshot, false);
|
||||||
@ -584,7 +584,7 @@ bool MemTracker::baseline() {
|
|||||||
// print memory usage from current snapshot
|
// print memory usage from current snapshot
|
||||||
bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
|
bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
|
||||||
MemBaseline baseline;
|
MemBaseline baseline;
|
||||||
MutexLockerEx lock(_query_lock, true);
|
MutexLocker lock(_query_lock);
|
||||||
MemSnapshot* snapshot = get_snapshot();
|
MemSnapshot* snapshot = get_snapshot();
|
||||||
if (snapshot != NULL && baseline.baseline(*snapshot, summary_only)) {
|
if (snapshot != NULL && baseline.baseline(*snapshot, summary_only)) {
|
||||||
BaselineReporter reporter(out, unit);
|
BaselineReporter reporter(out, unit);
|
||||||
@ -597,7 +597,7 @@ bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool sum
|
|||||||
// Whitebox API for blocking until the current generation of NMT data has been merged
|
// Whitebox API for blocking until the current generation of NMT data has been merged
|
||||||
bool MemTracker::wbtest_wait_for_data_merge() {
|
bool MemTracker::wbtest_wait_for_data_merge() {
|
||||||
// NMT can't be shutdown while we're holding _query_lock
|
// NMT can't be shutdown while we're holding _query_lock
|
||||||
MutexLockerEx lock(_query_lock, true);
|
MutexLocker lock(_query_lock);
|
||||||
assert(_worker_thread != NULL, "Invalid query");
|
assert(_worker_thread != NULL, "Invalid query");
|
||||||
// the generation at query time, so NMT will spin till this generation is processed
|
// the generation at query time, so NMT will spin till this generation is processed
|
||||||
unsigned long generation_at_query_time = SequenceGenerator::current_generation();
|
unsigned long generation_at_query_time = SequenceGenerator::current_generation();
|
||||||
@ -641,7 +641,7 @@ bool MemTracker::wbtest_wait_for_data_merge() {
|
|||||||
|
|
||||||
// compare memory usage between current snapshot and baseline
|
// compare memory usage between current snapshot and baseline
|
||||||
bool MemTracker::compare_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
|
bool MemTracker::compare_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
|
||||||
MutexLockerEx lock(_query_lock, true);
|
MutexLocker lock(_query_lock);
|
||||||
if (_baseline.baselined()) {
|
if (_baseline.baselined()) {
|
||||||
MemBaseline baseline;
|
MemBaseline baseline;
|
||||||
MemSnapshot* snapshot = get_snapshot();
|
MemSnapshot* snapshot = get_snapshot();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user