提交 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. * 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 @@ ...@@ -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) ...@@ -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) {
...@@ -344,16 +355,27 @@ bool MemBaseline::baseline_vm_details(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 // 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;
} }
......
/* /*
* 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 { ...@@ -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) { ...@@ -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() { ...@@ -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 ...@@ -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() { ...@@ -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();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册