提交 824b1209 编写于 作者: D dbuck

8059036: Implement Diagnostic Commands for heap and finalizerinfo

Summary: Implement Diagnostic Commands for heap and finalizerinfo
Reviewed-by: mchung
上级 c22b626d
/* /*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2017, 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
...@@ -569,6 +569,11 @@ ...@@ -569,6 +569,11 @@
template(java_lang_management_ThreadInfo_constructor_signature, "(Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;)V") \ template(java_lang_management_ThreadInfo_constructor_signature, "(Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;)V") \
template(java_lang_management_ThreadInfo_with_locks_constructor_signature, "(Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;[Ljava/lang/Object;[I[Ljava/lang/Object;)V") \ template(java_lang_management_ThreadInfo_with_locks_constructor_signature, "(Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;[Ljava/lang/Object;[I[Ljava/lang/Object;)V") \
template(long_long_long_long_void_signature, "(JJJJ)V") \ template(long_long_long_long_void_signature, "(JJJJ)V") \
template(finalizer_histogram_klass, "java/lang/ref/FinalizerHistogram") \
template(void_finalizer_histogram_entry_array_signature, "()[Ljava/lang/ref/FinalizerHistogram$Entry;") \
template(get_finalizer_histogram_name, "getFinalizerHistogram") \
template(finalizer_histogram_entry_name_field, "className") \
template(finalizer_histogram_entry_count_field, "instanceCount") \
\ \
template(java_lang_management_MemoryPoolMXBean, "java/lang/management/MemoryPoolMXBean") \ template(java_lang_management_MemoryPoolMXBean, "java/lang/management/MemoryPoolMXBean") \
template(java_lang_management_MemoryManagerMXBean, "java/lang/management/MemoryManagerMXBean") \ template(java_lang_management_MemoryManagerMXBean, "java/lang/management/MemoryManagerMXBean") \
......
/* /*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2017, 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
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "services/heapDumper.hpp" #include "services/heapDumper.hpp"
#include "services/management.hpp" #include "services/management.hpp"
#include "utilities/macros.hpp" #include "utilities/macros.hpp"
#include "oops/objArrayOop.hpp"
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
...@@ -49,6 +50,8 @@ void DCmdRegistrant::register_dcmds(){ ...@@ -49,6 +50,8 @@ void DCmdRegistrant::register_dcmds(){
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapInfoDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<FinalizerInfoDCmd>(full_export, true, false));
#if INCLUDE_SERVICES // Heap dumping/inspection supported #if INCLUDE_SERVICES // Heap dumping/inspection supported
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(full_export, true, false));
...@@ -273,6 +276,60 @@ void RunFinalizationDCmd::execute(DCmdSource source, TRAPS) { ...@@ -273,6 +276,60 @@ void RunFinalizationDCmd::execute(DCmdSource source, TRAPS) {
vmSymbols::void_method_signature(), CHECK); vmSymbols::void_method_signature(), CHECK);
} }
void HeapInfoDCmd::execute(DCmdSource source, TRAPS) {
Universe::heap()->print_on(output());
}
void FinalizerInfoDCmd::execute(DCmdSource source, TRAPS) {
ResourceMark rm;
Klass* k = SystemDictionary::resolve_or_null(
vmSymbols::finalizer_histogram_klass(), THREAD);
assert(k != NULL, "FinalizerHistogram class is not accessible");
instanceKlassHandle klass(THREAD, k);
JavaValue result(T_ARRAY);
// We are calling lang.ref.FinalizerHistogram.getFinalizerHistogram() method
// and expect it to return array of FinalizerHistogramEntry as Object[]
JavaCalls::call_static(&result, klass,
vmSymbols::get_finalizer_histogram_name(),
vmSymbols::void_finalizer_histogram_entry_array_signature(), CHECK);
objArrayOop result_oop = (objArrayOop) result.get_jobject();
if (result_oop->length() == 0) {
output()->print_cr("No instances waiting for finalization found");
return;
}
oop foop = result_oop->obj_at(0);
InstanceKlass* ik = InstanceKlass::cast(foop->klass());
fieldDescriptor count_fd, name_fd;
Klass* count_res = ik->find_field(
vmSymbols::finalizer_histogram_entry_count_field(), vmSymbols::int_signature(), &count_fd);
Klass* name_res = ik->find_field(
vmSymbols::finalizer_histogram_entry_name_field(), vmSymbols::string_signature(), &name_fd);
assert(count_res != NULL && name_res != NULL, "Unexpected layout of FinalizerHistogramEntry");
output()->print_cr("Unreachable instances waiting for finalization");
output()->print_cr("#instances class name");
output()->print_cr("-----------------------");
for (int i = 0; i < result_oop->length(); ++i) {
oop element_oop = result_oop->obj_at(i);
oop str_oop = element_oop->obj_field(name_fd.offset());
char *name = java_lang_String::as_utf8_string(str_oop);
int count = element_oop->int_field(count_fd.offset());
output()->print_cr("%10d %s", count, name);
}
}
#if INCLUDE_SERVICES // Heap dumping/inspection supported #if INCLUDE_SERVICES // Heap dumping/inspection supported
HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) : HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap), DCmdWithParser(output, heap),
......
/* /*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2017, 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
...@@ -176,6 +176,46 @@ public: ...@@ -176,6 +176,46 @@ public:
virtual void execute(DCmdSource source, TRAPS); virtual void execute(DCmdSource source, TRAPS);
}; };
class HeapInfoDCmd : public DCmd {
public:
HeapInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
static const char* name() { return "GC.heap_info"; }
static const char* description() {
return "Provide generic Java heap information.";
}
static const char* impact() {
return "Medium";
}
static int num_arguments() { return 0; }
static const JavaPermission permission() {
JavaPermission p = {"java.lang.management.ManagementPermission",
"monitor", NULL};
return p;
}
virtual void execute(DCmdSource source, TRAPS);
};
class FinalizerInfoDCmd : public DCmd {
public:
FinalizerInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
static const char* name() { return "GC.finalizer_info"; }
static const char* description() {
return "Provide information about Java finalization queue.";
}
static const char* impact() {
return "Medium";
}
static int num_arguments() { return 0; }
static const JavaPermission permission() {
JavaPermission p = {"java.lang.management.ManagementPermission",
"monitor", NULL};
return p;
}
virtual void execute(DCmdSource source, TRAPS);
};
#if INCLUDE_SERVICES // Heap dumping supported #if INCLUDE_SERVICES // Heap dumping supported
// See also: dump_heap in attachListener.cpp // See also: dump_heap in attachListener.cpp
class HeapDumpDCmd : public DCmdWithParser { class HeapDumpDCmd : public DCmdWithParser {
......
/*
* Copyright (c) 2015, 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.oracle.java.testlibrary.JDKToolFinder;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.ProcessTools;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/*
* @test
* @summary
* @library /testlibrary
* @run main FinalizerInfoTest
*/
public class FinalizerInfoTest {
static ReentrantLock lock = new ReentrantLock();
static volatile int wasInitialized = 0;
static volatile int wasTrapped = 0;
static final String cmd = "GC.finalizer_info";
static final int objectsCount = 1000;
class MyObject {
public MyObject() {
// Make sure object allocation/deallocation is not optimized out
wasInitialized += 1;
}
protected void finalize() {
// Trap the object in a finalization queue
wasTrapped += 1;
lock.lock();
}
}
void run() throws Exception {
try {
lock.lock();
for(int i = 0; i < objectsCount; ++i) {
new MyObject();
}
System.out.println("Objects initialized: " + objectsCount);
System.gc();
while(wasTrapped < 1) {
// Waiting for gc thread.
}
String pid = Integer.toString(ProcessTools.getProcessId());
ProcessBuilder pb = new ProcessBuilder();
pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, cmd});
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("MyObject");
} finally {
lock.unlock();
}
}
public static void main(String[] args) throws Exception {
new FinalizerInfoTest().run();
}
}
/*
* Copyright (c) 2015, 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.oracle.java.testlibrary.JDKToolFinder;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.ProcessTools;
/*
* @test
* @summary Test of diagnostic command GC.heap_info
* @library /testlibrary
* @run main HeapInfoTest
*/
public class HeapInfoTest {
public static void main(String[] args) throws Exception {
String pid = Integer.toString(ProcessTools.getProcessId());
ProcessBuilder pb = new ProcessBuilder();
pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "GC.heap_info"});
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("Metaspace");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册