/* * Copyright (c) 2012, 2022, 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. *
*/
if (startup) { if (log_is_enabled(Warning, jfr, startup)) { // if warning is set, assume user hasn't configured log level // Log to Info and reset to Warning. This way user can disable // default output by setting -Xlog:jfr+startup=error/off
LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(jfr, startup));
log(result, THREAD);
LogConfiguration::configure_stdout(LogLevel::Warning, true, LOG_TAGS(jfr, startup));
} else {
log(result, THREAD);
}
} else { // Print output for jcmd or MXBean
print_message(output, result, THREAD);
}
}
void JfrDCmd::parse(CmdLine* line, char delim, TRAPS) {
_args = line->args_addr();
_delimiter = delim; // Error checking done in execute. // Will not matter from DCmdFactory perspective // where parse and execute are called consecutively.
}
void JfrDCmd::execute(DCmdSource source, TRAPS) { if (invalid_state(output(), THREAD)) { return;
} staticconstchar signature[] = "(Ljava/lang/String;Ljava/lang/String;C)[Ljava/lang/String;";
JavaValue result(T_OBJECT);
JfrJavaArguments execute(&result, javaClass(), "execute", signature, CHECK);
jstring argument = JfrJavaSupport::new_string(_args, CHECK);
jstring s = NULL; if (source == DCmd_Source_Internal) {
s = JfrJavaSupport::new_string("internal", CHECK);
} if (source == DCmd_Source_MBean) {
s = JfrJavaSupport::new_string("mbean", CHECK);
} if (source == DCmd_Source_AttachAPI) {
s = JfrJavaSupport::new_string("attach", CHECK);
}
execute.push_jobject(s);
execute.push_jobject(argument);
execute.push_int(_delimiter);
invoke(execute, THREAD);
handle_dcmd_result(output(), result.get_oop(), source, THREAD);
}
staticvoid initialize_dummy_descriptors(GrowableArray<DCmdArgumentInfo*>* array) {
assert(array != NULL, "invariant");
DCmdArgumentInfo * const dummy = new DCmdArgumentInfo(NULL,
NULL,
NULL,
NULL, false, true, // a DcmdFramework "option" false); for (int i = 0; i < array->capacity(); ++i) {
array->append(dummy);
}
}
// Since the DcmdFramework does not support dynamically allocated strings, // we keep them in a thread local arena. The arena is reset between invocations. static THREAD_LOCAL Arena* dcmd_arena = NULL;
staticvoid prepare_dcmd_string_arena(JavaThread* jt) {
dcmd_arena = JfrThreadLocal::dcmd_arena(jt);
assert(dcmd_arena != nullptr, "invariant");
dcmd_arena->destruct_contents(); // will grow on next allocation
}
GrowableArray<DCmdArgumentInfo*>* JfrDCmd::argument_info_array() const { staticconstchar signature[] = "()[Ljdk/jfr/internal/dcmd/Argument;";
JavaThread* thread = JavaThread::current();
GrowableArray<DCmdArgumentInfo*>* const array = new GrowableArray<DCmdArgumentInfo*>(_num_arguments);
JavaValue result(T_OBJECT);
JfrJavaArguments getArgumentInfos(&result, javaClass(), "getArgumentInfos", signature, thread);
invoke(getArgumentInfos, thread); if (thread->has_pending_exception()) { // Most likely an OOME, but the DCmdFramework is not the best place to handle it. // We handle it locally by clearing the exception and returning an array with dummy descriptors. // This lets the MBean server initialization routine complete successfully, // but this particular command will have no argument descriptors exposed. // Hence we postpone, or delegate, handling of OOME's to code that is better suited.
log_debug(jfr, system)("Exception in DCmd getArgumentInfos");
thread->clear_pending_exception();
initialize_dummy_descriptors(array);
assert(array->length() == _num_arguments, "invariant"); return array;
}
objArrayOop arguments = objArrayOop(result.get_oop());
assert(arguments != NULL, "invariant");
assert(arguments->is_array(), "must be array"); constint num_arguments = arguments->length();
assert(num_arguments == _num_arguments, "invariant");
prepare_dcmd_string_arena(thread); for (int i = 0; i < num_arguments; ++i) {
DCmdArgumentInfo* const dai = create_info(arguments->obj_at(i), thread);
assert(dai != NULL, "invariant");
array->append(dai);
} return array;
}
GrowableArray<constchar*>* JfrDCmd::argument_name_array() const {
GrowableArray<DCmdArgumentInfo*>* argument_infos = argument_info_array();
GrowableArray<constchar*>* array = new GrowableArray<constchar*>(argument_infos->length()); for (int i = 0; i < argument_infos->length(); i++) {
array->append(argument_infos->at(i)->name());
} return array;
}
JfrConfigureFlightRecorderDCmd::JfrConfigureFlightRecorderDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap),
_repository_path("repositorypath", "Path to repository,.e.g \\\"My Repository\\\"", "STRING", false, NULL),
_dump_path("dumppath", "Path to dump,.e.g \\\"My Dump path\\\"", "STRING", false, NULL),
_stack_depth("stackdepth", "Stack Depth", "JULONG", false, "64"),
_global_buffer_count("globalbuffercount", "Number of global buffers,", "JULONG", false, "20"),
_global_buffer_size("globalbuffersize", "Size of a global buffers,", "MEMORY SIZE", false, "512k"),
_thread_buffer_size("thread_buffer_size", "Size of a thread buffer", "MEMORY SIZE", false, "8k"),
_memory_size("memorysize", "Overall memory size, ", "MEMORY SIZE", false, "10m"),
_max_chunk_size("maxchunksize", "Size of an individual disk chunk", "MEMORY SIZE", false, "12m"),
_sample_threads("samplethreads", "Activate Thread sampling", "BOOLEAN", false, "true"),
_verbose(true) {
_dcmdparser.add_dcmd_option(&_repository_path);
_dcmdparser.add_dcmd_option(&_dump_path);
_dcmdparser.add_dcmd_option(&_stack_depth);
_dcmdparser.add_dcmd_option(&_global_buffer_count);
_dcmdparser.add_dcmd_option(&_global_buffer_size);
_dcmdparser.add_dcmd_option(&_thread_buffer_size);
_dcmdparser.add_dcmd_option(&_memory_size);
_dcmdparser.add_dcmd_option(&_max_chunk_size);
_dcmdparser.add_dcmd_option(&_sample_threads);
};
void JfrConfigureFlightRecorderDCmd::print_help(constchar* name) const {
outputStream* out = output(); // 0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890
out->print_cr("Options:");
out->print_cr("");
out->print_cr(" globalbuffercount (Optional) Number of global buffers. This option is a legacy");
out->print_cr(" option: change the memorysize parameter to alter the number of");
out->print_cr(" global buffers. This value cannot be changed once JFR has been");
out->print_cr(" initialized. (STRING, default determined by the value for");
out->print_cr(" memorysize)");
out->print_cr("");
out->print_cr(" globalbuffersize (Optional) Size of the global buffers, in bytes. This option is a");
out->print_cr(" legacy option: change the memorysize parameter to alter the size");
out->print_cr(" of the global buffers. This value cannot be changed once JFR has");
out->print_cr(" been initialized. (STRING, default determined by the value for");
out->print_cr(" memorysize)");
out->print_cr("");
out->print_cr(" maxchunksize (Optional) Maximum size of an individual data chunk in bytes if");
out->print_cr(" one of the following suffixes is not used: 'm' or 'M' for");
out->print_cr(" megabytes OR 'g' or 'G' for gigabytes. This value cannot be");
out->print_cr(" changed once JFR has been initialized. (STRING, 12M)");
out->print_cr("");
out->print_cr(" memorysize (Optional) Overall memory size, in bytes if one of the following");
out->print_cr(" suffixes is not used: 'm' or 'M' for megabytes OR 'g' or 'G' for");
out->print_cr(" gigabytes. This value cannot be changed once JFR has been");
out->print_cr(" initialized. (STRING, 10M)");
out->print_cr("");
out->print_cr(" repositorypath (Optional) Path to the location where recordings are stored until");
out->print_cr(" they are written to a permanent file. (STRING, The default");
out->print_cr(" location is the temporary directory for the operating system. On");
out->print_cr(" Linux operating systems, the temporary directory is /tmp. On");
out->print_cr(" Windows, the temporary directory is specified by the TMP");
out->print_cr(" environment variable)");
out->print_cr("");
out->print_cr(" dumppath (Optional) Path to the location where a recording file is written");
out->print_cr(" in case the VM runs into a critical error, such as a system");
out->print_cr(" crash. (STRING, The default location is the current directory)");
out->print_cr("");
out->print_cr(" stackdepth (Optional) Stack depth for stack traces. Setting this value");
out->print_cr(" greater than the default of 64 may cause a performance");
out->print_cr(" degradation. This value cannot be changed once JFR has been");
out->print_cr(" initialized. (LONG, 64)");
out->print_cr("");
out->print_cr(" thread_buffer_size (Optional) Local buffer size for each thread in bytes if one of");
out->print_cr(" the following suffixes is not used: 'k' or 'K' for kilobytes or");
out->print_cr(" 'm' or 'M' for megabytes. Overriding this parameter could reduce");
out->print_cr(" performance and is not recommended. This value cannot be changed");
out->print_cr(" once JFR has been initialized. (STRING, 8k)");
out->print_cr("");
out->print_cr("Options must be specified using the or = syntax.");
out->print_cr("");
out->print_cr("Example usage:");
out->print_cr("");
out->print_cr(" $ jcmd JFR.configure");
out->print_cr(" $ jcmd JFR.configure repositorypath=/temporary");
out->print_cr(" $ jcmd JFR.configure stackdepth=256");
out->print_cr(" $ jcmd JFR.configure memorysize=100M");
out->print_cr("");
}
int JfrConfigureFlightRecorderDCmd::num_arguments() {
ResourceMark rm;
JfrConfigureFlightRecorderDCmd* dcmd = new JfrConfigureFlightRecorderDCmd(NULL, false); if (dcmd != NULL) {
DCmdMark mark(dcmd); return dcmd->_dcmdparser.num_arguments();
} return 0;
}
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.