提交 839d6674 编写于 作者: Z zgu

8011218: Kitchensink hanged, likely NMT is to blame

Summary: Made NMT query safepoint aware.
Reviewed-by: dholmes, coleenp
上级 7502cd7a
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -23,9 +23,12 @@
*/
#include "precompiled.hpp"
#include "memory/allocation.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/thread.inline.hpp"
#include "services/memBaseline.hpp"
#include "services/memTracker.hpp"
MemType2Name MemBaseline::MemType2NameMap[NUMBER_OF_MEMORY_TYPE] = {
{mtJavaHeap, "Java Heap"},
{mtClass, "Class"},
......@@ -149,6 +152,14 @@ bool MemBaseline::baseline_malloc_summary(const MemPointerArray* malloc_records)
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
// memory types
bool MemBaseline::baseline_vm_summary(const MemPointerArray* vm_records) {
......@@ -344,16 +355,27 @@ bool MemBaseline::baseline_vm_details(const MemPointerArray* vm_records) {
// baseline a snapshot. If summary_only = false, memory usages aggregated by
// 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) {
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();
_baselined = baseline_malloc_summary(snapshot._alloc_ptrs) &&
baseline_vm_summary(snapshot._vm_ptrs);
_baselined = baseline_malloc_summary(snapshot._alloc_ptrs);
if (_baselined) {
check_safepoint((JavaThread*)THREAD);
_baselined = baseline_vm_summary(snapshot._vm_ptrs);
}
_number_of_classes = snapshot.number_of_classes();
if (!summary_only && MemTracker::track_callsite() && _baselined) {
_baselined = baseline_malloc_details(snapshot._alloc_ptrs) &&
baseline_vm_details(snapshot._vm_ptrs);
check_safepoint((JavaThread*)THREAD);
_baselined = baseline_malloc_details(snapshot._alloc_ptrs);
if (_baselined) {
check_safepoint((JavaThread*)THREAD);
_baselined = baseline_vm_details(snapshot._vm_ptrs);
}
}
return _baselined;
}
......
/*
* 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.
*
* 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
MemBaseline(MemBaseline& copy) { ShouldNotReachHere(); }
// check and block at a safepoint
static inline void check_safepoint(JavaThread* thr);
public:
// create a memory baseline
MemBaseline();
......
......@@ -573,7 +573,7 @@ void MemTracker::thread_exiting(JavaThread* thread) {
// baseline current memory snapshot
bool MemTracker::baseline() {
MutexLockerEx lock(_query_lock, true);
MutexLocker lock(_query_lock);
MemSnapshot* snapshot = get_snapshot();
if (snapshot != NULL) {
return _baseline.baseline(*snapshot, false);
......@@ -584,7 +584,7 @@ bool MemTracker::baseline() {
// print memory usage from current snapshot
bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
MemBaseline baseline;
MutexLockerEx lock(_query_lock, true);
MutexLocker lock(_query_lock);
MemSnapshot* snapshot = get_snapshot();
if (snapshot != NULL && baseline.baseline(*snapshot, summary_only)) {
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
bool MemTracker::wbtest_wait_for_data_merge() {
// 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");
// the generation at query time, so NMT will spin till this generation is processed
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
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()) {
MemBaseline baseline;
MemSnapshot* snapshot = get_snapshot();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册