Java Virtual Machine Guide
Java Virtual Machine Guide
Java Virtual Machine Guide
Release 20
F73076-01
March 2023
Java Platform, Standard Edition Java Virtual Machine Guide, Release 20
F73076-01
This software and related documentation are provided under a license agreement containing restrictions on
use and disclosure and are protected by intellectual property laws. Except as expressly permitted in your
license agreement or allowed by law, you may not use, copy, reproduce, translate, broadcast, modify, license,
transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any means. Reverse
engineering, disassembly, or decompilation of this software, unless required by law for interoperability, is
prohibited.
The information contained herein is subject to change without notice and is not warranted to be error-free. If
you find any errors, please report them to us in writing.
If this is software, software documentation, data (as defined in the Federal Acquisition Regulation), or related
documentation that is delivered to the U.S. Government or anyone licensing it on behalf of the U.S.
Government, then the following notice is applicable:
U.S. GOVERNMENT END USERS: Oracle programs (including any operating system, integrated software,
any programs embedded, installed, or activated on delivered hardware, and modifications of such programs)
and Oracle computer documentation or other Oracle data delivered to or accessed by U.S. Government end
users are "commercial computer software," "commercial computer software documentation," or "limited rights
data" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental
regulations. As such, the use, reproduction, duplication, release, display, disclosure, modification, preparation
of derivative works, and/or adaptation of i) Oracle programs (including any operating system, integrated
software, any programs embedded, installed, or activated on delivered hardware, and modifications of such
programs), ii) Oracle computer documentation and/or iii) other Oracle data, is subject to the rights and
limitations specified in the license contained in the applicable contract. The terms governing the U.S.
Government's use of Oracle cloud services are defined by the applicable contract for such services. No other
rights are granted to the U.S. Government.
This software or hardware is developed for general use in a variety of information management applications.
It is not developed or intended for use in any inherently dangerous applications, including applications that
may create a risk of personal injury. If you use this software or hardware in dangerous applications, then you
shall be responsible to take all appropriate fail-safe, backup, redundancy, and other measures to ensure its
safe use. Oracle Corporation and its affiliates disclaim any liability for any damages caused by use of this
software or hardware in dangerous applications.
Oracle®, Java, and MySQL are registered trademarks of Oracle and/or its affiliates. Other names may be
trademarks of their respective owners.
Intel and Intel Inside are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks are
used under license and are trademarks or registered trademarks of SPARC International, Inc. AMD, Epyc,
and the AMD logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a registered
trademark of The Open Group.
This software or hardware and documentation may provide access to or information about content, products,
and services from third parties. Oracle Corporation and its affiliates are not responsible for and expressly
disclaim all warranties of any kind with respect to third-party content, products, and services unless otherwise
set forth in an applicable agreement between you and Oracle. Oracle Corporation and its affiliates will not be
responsible for any loss, costs, or damages incurred due to your access to or use of third-party content,
products, or services, except as set forth in an applicable agreement between you and Oracle.
Contents
Preface
Audience vi
Documentation Accessibility vi
Diversity and Inclusion vi
Related Documents vi
Conventions vi
2 Compiler Control
Writing Directives 2-1
Compiler Control Options 2-2
Writing a Directive File 2-5
Writing a Compiler Directive 2-6
Writing a Method Pattern in a Compiler Directive 2-8
Writing an Inline Directive Option 2-9
Preventing Duplication with the Enable Option 2-10
Understanding Directives 2-11
What Is the Default Directive? 2-11
How Directives are Applied to Code? 2-14
Compiler Control and Backward Compatibility 2-15
Commands for Working with Directive Files 2-16
Compiler Directives and the Command Line 2-16
Compiler Directives and Diagnostic Commands 2-17
Getting Your Java Process Identification Number 2-17
Adding Directives Through Diagnostic Commands 2-17
Removing Directives Through Diagnostic Commands 2-18
Printing Directives Through Diagnostic Commands 2-18
How Directives Are Ordered in the Directives Stack? 2-18
iii
3 Garbage Collection
8 Signal Chaining
iv
Using Native Memory Tracking 9-1
Enabling NMT 9-1
Accessing NMT Data using jcmd 9-2
Obtaining NMT Data at VM Exit 9-2
v
Preface
Preface
This document provides information about the features supported by Java Virtual
Machine technology.
Audience
This document is intended for experienced developers who build applications using
the Java HotSpot technology.
Documentation Accessibility
For information about Oracle's commitment to accessibility, visit the Oracle
Accessibility Program website at http://www.oracle.com/pls/topic/lookup?
ctx=acc&id=docacc.
Related Documents
See JDK 20 Documentation for other JDK 20 guides.
Conventions
The following text conventions are used in this document:
vi
Preface
Convention Meaning
boldface Boldface type indicates graphical user interface elements associated with an
action, or terms defined in text.
italic Italic type indicates book titles, emphasis, or placeholder variables for which
you supply particular values.
monospace Monospace type indicates commands within a paragraph, URLs, code in
examples, text that appears on the screen, or text that you enter.
vii
1
Java Virtual Machine Technology Overview
This chapter describes the implementation of the Java Virtual Machine (JVM) and the main
features of the Java HotSpot technology:
• Adaptive compiler: A standard interpreter is used to launch the applications. When the
application runs, the code is analyzed to detect performance bottlenecks, or hot spots.
The Java HotSpot VM compiles the performance-critical portions of the code for a boost
in performance, but does not compile the seldom-used code (most of the application).
The Java HotSpot VM uses the adaptive compiler to decide how to optimize compiled
code with techniques such as inlining.
• Rapid memory allocation and garbage collection: Java HotSpot technology provides
rapid memory allocation for objects and fast, efficient, state-of-the-art garbage collectors.
• Thread synchronization: Java HotSpot technology provides a thread-handling capability
that is designed to scale for use in large, shared-memory multiprocessor servers.
In Oracle Java Runtime Environment (JRE) 8 and earlier, different implementations of the
JVM, (the client VM, server VM, and minimal VM) were supported for configurations
commonly used as clients, as servers, and for embedded systems. Because most systems
can now take advantage of the server VM, only that VM implementation is provided in later
versions.
1-1
2
Compiler Control
Compiler Control provides a way to control Java Virtual Machine (JVM) compilation through
compiler directive options. The level of control is runtime-manageable and method specific.
A compiler directive is an instruction that tells the JVM how compilation should occur. A
directive provides method-context precision in controlling the compilation process. You can
use directives to write small, contained, JVM compiler tests that can run without restarting the
entire JVM. You can also use directives to create workarounds for bugs, in the JVM
compilers.
You can specify a file that contains compiler directives when you start a program through the
command line. You can also add or remove directives from an already running program by
using diagnostic commands.
Compiler Control supersedes and is backward compatible with CompileCommand.
Topics:
• Writing Directives
– Writing a Directive File
– Writing a Compiler Directive
– Writing a Method Pattern in a Compiler Directive
– Writing an Inline Directive Option
– Preventing Duplication with the Enable Option
• Understanding Directives
– What Is the Default Directive?
– How Directives are Applied to Code?
– Compiler Control and Backward Compatibility
• Commands for Working with Directive Files
– Compiler Directives and the Command Line
– Compiler Directives and Diagnostic Commands
– How Directives Are Ordered in the Directives Stack?
Writing Directives
This topic examines Compiler Control options and steps for writing directives from those
options.
Topics:
• Compiler Control Options
• Writing a Directive File
2-1
Chapter 2
Writing Directives
2-2
Chapter 2
Writing Directives
2-3
Chapter 2
Writing Directives
2-4
Chapter 2
Writing Directives
A ccstr value type is a method pattern. See Writing a Method Pattern in a Compiler
Directive.
The default directive supplies default values for compiler options. See What Is the Default
Directive?
[ //Array of Directives
{ //Directive Block
//Directive 1
},
{ //Directive Block
//Directive 2
},
]
2-5
Chapter 2
Writing Directives
[ //Array of directives
{ //Directive Block
//Directive 1
match: ["java*.*", "oracle*.*"],
c1: {
Enable: true,
Exclude: true,
BreakAtExecute: true,
},
c2: {
Enable: false,
MaxNodeLimit: 1000,
},
BreakAtCompile: true,
DumpReplay: true,
},
{ //Directive Block
//Directive 2
match: ["*Concurrent.*"],
c2: {
Exclude:true,
},
},
]
2-6
Chapter 2
Writing Directives
1. Insert the following block of code, as a template you can work from, to write an individual
compiler directive. This block of code is a directive block.
{
match: [],
c1: {
//c1 directive options
},
c2: {
//c2 directive options
},
//Directive options applicable to all compilers
},
2. Provide the match attribute with an array of method patterns. See Writing a Method
Pattern in a Compiler Directive.
For example:
3. Provide the c1 attribute with a block of comma-separated directive options. Ensure that
these options are valid for the c1 compiler.
For example:
c1: {
Enable: true,
Exclude: true,
BreakAtExecute: true,
},
4. Provide the c2 attribute with a block of comma-separated directive options. This block
can contain a mix of common and c2-exclusive compiler options.
For example:
c2: {
Enable: false,
MaxNodeLimit: 1000,
},
5. Provide, at the end of the directive, options you want applicable to all compilers. These
options are considered written within the scope of the common block. Options are
comma-separated.
For example:
BreakAtCompile: true,
DumpReplay: true,
2-7
Chapter 2
Writing Directives
b. Avoid writing c2-exclusive directive options in the common block. Although the
common block can accept a mix of common and c2-exclusive options, it’s
pointless to structure a directive this way because c2-exclusive options in the
common block have no effect on the c1 compiler. Write c2-exclusive options
within the c2 block instead.
c. If the c1 or c2 attribute has no corresponding directive options, then omit the
attribute-value syntax for that compiler.
The following example shows the resulting directive, based on earlier examples, is:
{
match: ["java*.*", "oracle*.*"],
c1: {
Enable: true,
Exclude: true,
BreakAtExecute: true,
},
c2: {
Enable: false,
MaxNodeLimit: 1000,
},
BreakAtCompile: true,
DumpReplay: true,
},
The JSON format of directive files allows the following deviations in syntax:
• Extra trailing commas are optional in arrays and objects.
• Attributes are strings and are optionally placed within quotation marks.
• If an array contains only one element, then brackets are optional.
Therefore, the following example shows a valid compiler directive:
{
"match": "*Concurrent.*",
c2: {
"Exclude": true,
}
},
2-8
Chapter 2
Writing Directives
The following example shows a method pattern that uses this syntax:
java/lang/String.indexOf()
Other formatting styles are available. This ensures backward compatibility with earlier
ways of method matching such as CompileCommand. Valid formatting alternatives for the
previous example include:
• java/lang/String.indexOf()
• java/lang/String,indexOf()
• java/lang/String indexOf()
• java.lang.String::indexOf()
The last formatting style matches the HotSpot output.
2. Insert a wildcard character (*) where you want to generalize part of the method pattern.
The following examples are valid generalizations of the method pattern example in Step
1:
• java/lang/String.indexOf*
• *lang/String.indexOf*
• *va/lang*.*dex*
• java/lang/String.*
• *.*
Increased generalization leads to decreased precision. More Java code becomes a
potential match with the method pattern. Therefore, it’s important to use the wildcard
character (*) judiciously.
3. Modify the signature portion of the method pattern, according to the Java Specifications.
A signature match must be exact, otherwise the signature defaults to a wildcard character
(*). Omitted signatures also default to a wildcard character. Signatures cannot contain the
wildcard character.
4. Optional: If you write a method pattern to accompany the inline directive option, then
you must prefix the method pattern with additional characters. See Writing an Inline
Directive Option.
2-9
Chapter 2
Writing Directives
5. Optional: If you need inlining behavior applied to multiple method patterns, then
repeat Steps 1 to 4 to write multiple inline statements. Don’t write a single array
that contains multiple method patterns.
The following examples show the inline directive options:
• inline: ["+java/lang*.*", "-sun*.*"]
• inline: "+java/lang*.*"
[
{
match: ["java*.*"],
c1: {
BreakAtExecute: true,
BreakAtCompile: true,
DumpReplay: true,
DumpInline: true,
},
c2: {
MaxNodeLimit: 1000,
},
},
{
match: ["oracle*.*"],
c1: {
BreakAtExecute: true,
BreakAtCompile: true,
DumpReplay: true,
DumpInline: true,
},
c2: {
MaxNodeLimit: 2000,
},
},
]
The following example shows how the undesirable code duplication is resolved with
the Enable option. Enable hides the block directives and renders them unmatchable.
[
{
match: ["java*.*"],
c1: {
Enable: false,
},
c2: {
MaxNodeLimit: 1000,
2-10
Chapter 2
Understanding Directives
},
},
{
match: ["oracle*.*"],
c1: {
Enable: false,
},
c2: {
MaxNodeLimit: 2000,
},
},
{
match: ["java*.*", "oracle*.*"],
c1: {
BreakAtExecute: true,
BreakAtCompile: true,
DumpReplay: true,
DumpInline: true,
},
c2: {
//Unreachable code
},
},
]
Typically, the first matching directive is applied to a method’s compilation. The Enable option
provides an exception to this rule. A method that would typically be compiled by c1 in the first
or second directive is now compiled with the c1 block of the third directive. The c2 block of
the third directive is unreachable because the c2 blocks in the first and second directive take
priority.
Understanding Directives
The following topics examine how directives behave and interact.
Topics:
• What Is the Default Directive?
• How Directives are Applied to Code?
• Compiler Control and Backward Compatibility
2-11
Chapter 2
Understanding Directives
Directive: (default)
matching: *.*
c1 directives:
inline: -
Enable:true Exclude:false BreakAtExecute:false BreakAtCompile:false
Log:false PrintAssembly:false PrintInlining:false PrintNMethods:false
BackgroundCompilation:true ReplayInline:false DumpReplay:false
DumpInline:false CompilerDirectivesIgnoreCompileCommands:false
DisableIntrinsic: BlockLayoutByFrequency:true PrintOptoAssembly:false
PrintIntrinsics:false TraceOptoPipelining:false TraceOptoOutput:false
TraceSpilling:false Vectorize:false VectorizeDebug:0
CloneMapDebug:false IGVPrintLevel:0 MaxNodeLimit:80000
c2 directives:
inline: -
Enable:true Exclude:false BreakAtExecute:false BreakAtCompile:false
Log:false PrintAssembly:false PrintInlining:false PrintNMethods:false
BackgroundCompilation:true ReplayInline:false DumpReplay:false
DumpInline:false CompilerDirectivesIgnoreCompileCommands:false
DisableIntrinsic: BlockLayoutByFrequency:true PrintOptoAssembly:false
PrintIntrinsics:false TraceOptoPipelining:false TraceOptoOutput:false
TraceSpilling:false Vectorize:false VectorizeDebug:0
CloneMapDebug:false IGVPrintLevel:0 MaxNodeLimit:80000
Note:
Certain options are applicable exclusively to the c2 compiler. For a complete
list, see Table 2-2.
[
{
match: ["*Concurrent.*"],
c2: {
MaxNodeLimit: 1000,
},
Exclude:true,
},
]
2-12
Chapter 2
Understanding Directives
When you add a new directive to the directives stack, the default directive becomes the
bottom-most directive in the stack. See How Directives Are Ordered in the Directives Stack?
for a description of this process. For this example, when you print the directives stack, it
shows how the directive options specified in the new directive differ from the values in the
default directive:
Directive:
matching: *Concurrent.*
c1 directives:
inline: -
Enable:true Exclude:true BreakAtExecute:false BreakAtCompile:false
Log:false PrintAssembly:false PrintInlining:false PrintNMethods:false
BackgroundCompilation:true ReplayInline:false DumpReplay:false
DumpInline:false CompilerDirectivesIgnoreCompileCommands:false
DisableIntrinsic: BlockLayoutByFrequency:true PrintOptoAssembly:false
PrintIntrinsics:false TraceOptoPipelining:false TraceOptoOutput:false
TraceSpilling:false Vectorize:false VectorizeDebug:0 CloneMapDebug:false
IGVPrintLevel:0 MaxNodeLimit:80000
c2 directives:
inline: -
Enable:true Exclude:true BreakAtExecute:false BreakAtCompile:false
Log:false PrintAssembly:false PrintInlining:false PrintNMethods:false
BackgroundCompilation:true ReplayInline:false DumpReplay:false
DumpInline:false CompilerDirectivesIgnoreCompileCommands:false
DisableIntrinsic: BlockLayoutByFrequency:true PrintOptoAssembly:false
PrintIntrinsics:false TraceOptoPipelining:false TraceOptoOutput:false
TraceSpilling:false Vectorize:false VectorizeDebug:0 CloneMapDebug:false
IGVPrintLevel:0 MaxNodeLimit:1000
Directive: (default)
matching: *.*
c1 directives:
inline: -
Enable:true Exclude:false BreakAtExecute:false BreakAtCompile:false
Log:false PrintAssembly:false PrintInlining:false PrintNMethods:false
BackgroundCompilation:true ReplayInline:false DumpReplay:false
DumpInline:false CompilerDirectivesIgnoreCompileCommands:false
DisableIntrinsic: BlockLayoutByFrequency:true PrintOptoAssembly:false
PrintIntrinsics:false TraceOptoPipelining:false TraceOptoOutput:false
TraceSpilling:false Vectorize:false VectorizeDebug:0 CloneMapDebug:false
IGVPrintLevel:0 MaxNodeLimit:80000
c2 directives:
inline: -
Enable:true Exclude:false BreakAtExecute:false BreakAtCompile:false
Log:false PrintAssembly:false PrintInlining:false PrintNMethods:false
BackgroundCompilation:true ReplayInline:false DumpReplay:false
DumpInline:false CompilerDirectivesIgnoreCompileCommands:false
DisableIntrinsic: BlockLayoutByFrequency:true PrintOptoAssembly:false
PrintIntrinsics:false TraceOptoPipelining:false TraceOptoOutput:false
TraceSpilling:false Vectorize:false VectorizeDebug:0 CloneMapDebug:false
IGVPrintLevel:0 MaxNodeLimit:80000
2-13
Chapter 2
Understanding Directives
Directive 2:
matching: *.*example*
Directive 1:
matching: *.*exampleMethod*
Directive 0: (default)
matching: *.*
2-14
Chapter 2
Understanding Directives
Based on method-matching criteria, Directive 0 (the default directive) is applied from the
following example directive stack:
Directive 2:
matching: *.*example*
Directive 1:
matching: *.*exampleMethod*
Directive 0: (default)
matching: *.*
2-15
Chapter 2
Commands for Working with Directive Files
– BreakAtCompile: false
– Log: false
For the options and values in this example, the resulting compilation is determined by
using the rules for handling backward compatibility conflicts:
• Exclude: true
• BreakAtExecute: false
• BreakAtCompile: true
• Log: false
XX:CompilerDirectivesFile=file
Include this command-line option when you start a Java program. The following
example shows this option, which starts TestProgram:
java -XX:+UnlockDiagnosticVMOptions -
XX:CompilerDirectivesFile=File_A.json TestProgram
In the example:
• -XX:+UnlockDiagnosticVMOptions enables diagnostic options. You must enter
this before you add directives at the command line.
• -XX:CompilerDirectivesFile is a type of diagnostic option. You can use it to
specify one directives file to add to the directives stack.
2-16
Chapter 2
Commands for Working with Directive Files
• File_A.json is a directives file. The file can contain multiple directives, all of which are
added to the stack of active directives when the program starts.
• If File_A.json contains syntax errors or malformed directives, then an error message is
displayed and TestProgram does not start.
-XX:+CompilerDirectivesPrint
The following example shows how to include this diagnostic command at the command line:
11084 TestProgram
2-17
Chapter 2
Commands for Working with Directive Files
The terminal reports the number of individual directives added. If the directives file
contains syntax errors or malformed directives, then an error message is displayed,
and no directives from the file are added to the stack, and no changes are made to the
running program.
It’s not possible to specify an entire file of directives to remove, nor is any other way
available to remove directives in bulk.
2-18
Chapter 2
Commands for Working with Directive Files
• To start TestProgram without adding any directives, at the command line, enter the
following command:
java TestProgram
Directives Stack
java TestProgram
[ [ [
Directive 1 Directive 3 Directive 4
Directive 2 ] Directive 5 Directive 0
] ]
java -XX:+UnlockDiagnosticVMOptions -
XX:CompilerDirectivesFile=File_A.json TestProgram
• TestProgram starts and the directives in File_A are added to the stack. The top-most
directive in the directives file becomes the top-most directive in the directives stack.
• Figure 2-2 shows that the order of directives in the stack, from top to bottom, becomes is
[1, 2, 0].
Directives Stack
-XX: CompilerDirectivesFile=File_A.json
Directive 1
File_A File_B File_C
[ [ [ Directive 2
Directive 1 Directive 3 Directive 4
Directive 2 ] Directive 5 Directive 0
] ]
2-19
Chapter 2
Commands for Working with Directive Files
Directives Stack
Compiler.directives_add File_B.json
Directive 3
Directive 1
File_A File_B File_C
[ [ [ Directive 2
Directive 1 Directive 3 Directive 4
Directive 2 ] Directive 5 Directive 0
] ]
You can add directive files through diagnostic commands to the TestProgram while it is
running:
• To add all directives from File_C to the directives stack, enter the following
command.
• Figure 2-4 shows that the order of directives in the stack becomes is [4, 5, 3, 1, 2,
0].
Directives Stack
Compiler.directives_add File_C.json
Directive 4
Directive 5
Directive 3
Directive 1
File_A File_B File_C
[ [ [ Directive 2
Directive 1 Directive 3 Directive 4
Directive 2 ] Directive 5 Directive 0
] ]
2-20
Chapter 2
Commands for Working with Directive Files
• To remove more, repeat this diagnostic command until only the default directive remains.
You can’t remove the default directive.
• Figure 2-5 shows that the order of directives in the stack becomes is [5, 3, 1, 2, 0].
Directives Stack
Compiler.directives_remove
Directive 4
Directive 5
Directive 3
Directive 1
File_A File_B File_C
[ [ [ Directive 2
Directive 1 Directive 3 Directive 4
Directive 2 ] Directive 5 Directive 0
] ]
• All directives are removed except the default directive. You can’t remove the default
directive.
• Figure 2-6 shows that only Directive 0 remains in the stack.
Directives Stack
Compiler.directives_clear
Directive 5
Directive 3
Directive 1
File_A File_B File_C
[ [ [ Directive 2
Directive 1 Directive 3 Directive 4
Directive 2 ] Directive 5 Directive 0
] ]
2-21
3
Garbage Collection
Oracle’s HotSpot VM includes several garbage collectors that you can use to help optimize
the performance of your application. A garbage collector is especially helpful if your
application handles large amounts of data (multiple gigabytes), has many threads, and has
high transaction rates.
For descriptions on the available garbage collectors, see Garbage Collection Implementation
in the Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning
Guide.
3-1
4
Class Data Sharing
This chapter describes the class data sharing (CDS) feature that can help reduce the startup
time and memory footprints for Java applications.
Topics:
• Class Data Sharing
• Regenerating the Shared Archive
• Manually Controlling Class Data Sharing
• Generating CDS Archive Automatically
By default, the default CDS archive is enabled at the runtime. Specify -Xshare:off to disable
the default shared archive. See Regenerating the Shared Archive to create a customized
shared archive. Use the same Java heap size for both dump time and runtime while creating
and using a customized shared archive.
When the JVM starts, the shared archive is memory-mapped to allow sharing of read-only
JVM metadata for these classes among multiple JVM processes. Because accessing the
shared archive is faster than loading the classes, startup time is reduced.
Class data sharing is supported with the ZGC, G1, serial, and parallel garbage collectors.
The shared Java heap object feature (part of class data sharing) supports only the G1
garbage collector on 64-bit non-Windows platforms.
The primary motivation for including CDS in Java SE is to decrease in startup time. The
smaller the application relative to the number of core classes it uses, the larger the saved
fraction of startup time.
The footprint cost of new JVM instances has been reduced in two ways:
1. A portion of the shared archive on the same host is mapped as read-only and shared
among multiple JVM processes. Otherwise, this data would need to be replicated in each
JVM instance, which would increase the startup time of your application.
4-1
Chapter 4
Regenerating the Shared Archive
2. The shared archive contains class data in the form that the Java Hotspot VM uses
it. The memory that would otherwise be required to access the original class
information in the runtime modular image, is not used. These memory savings
allow more applications to be run concurrently on the same system. In Windows
applications, the memory footprint of a process, as measured by various tools,
might appear to increase, because more pages are mapped to the process’s
address space. This increase is offset by the reduced amount of memory (inside
Windows) that is needed to hold portions on the runtime modular image. Reducing
footprint remains a high priority.
4-2
Chapter 4
Manually Controlling Class Data Sharing
To regenerate the archive file log in as the administrator. In networked situations, log in to a
computer of the same architecture as the Java SE installation. Ensure that you have
permissions to write to the installation directory.
To regenerate the shared archive by using a user defined class list, enter the following
command:
jcmd <pid or AppName> VM.cds <subcommand> <filename>
-Xshare:off
To disable class data sharing.
-Xshare:on
To enable class data sharing. If class data sharing can't be enabled, print an error message
and exit.
Note:
The -Xshare:on is for testing purposes only. It may cause the VM to unexpectedly
exit during start-up when the CDS archive cannot be used (for example, when
certain VM parameters are changed, or when a different JDK is used). This option
should not be used in production environments.
-Xshare:auto
To enable class data sharing by default. Enable class data sharing whenever possible.
The specified archive file will be created if it does not exist, or if it was generated by a
different JDK version.
See Creating Dynamic CDS Archive File with -XX:+AutoCreateSharedArchive in Java
Development Kit Tool Specifications.
4-3
5
Java HotSpot Virtual Machine Performance
Enhancements
This chapter describes the performance enhancements in the Oracle’s HotSpot Virtual
Machine technology.
Topics:
• Compact Strings
• Tiered Compilation
• Compressed Ordinary Object Pointer
• Zero-Based Compressed Ordinary Object Pointers
• Escape Analysis
Compact Strings
The compact strings feature introduces a space-efficient internal representation for strings.
Data from different applications suggests that strings are a major component of Java heap
usage and that most java.lang.String objects contain only Latin-1 characters. Such
characters require only one byte of storage. As a result, half of the space in the internal
character arrays of java.lang.String objects are not used. The compact strings feature,
introduced in Java SE 9 reduces the memory footprint, and reduces garbage collection
activity. This feature can be disabled if you observe performance regression issues in an
application.
The compact strings feature does not introduce new public APIs or interfaces. It modifies the
internal representation of the java.lang.String class from a UTF-16 (two bytes) character
array to a byte array with an additional field to identify character encoding. Other string-
related classes, such as AbstractStringBuilder, StringBuilder, and StringBuffer are
updated to use a similar internal representation.
In Java SE 9, the compact strings feature is enabled by default. Therefore, the
java.lang.String class stores characters as one byte for each character, encoded as
Latin-1. The additional character encoding field indicates the encoding that is used. The
HotSpot VM string intrinsics are updated and optimized to support the internal representation.
You can disable the compact strings feature by using the -XX:-CompactStrings flag with the
java command line. When the feature is disabled, the java.lang.String class stores
characters as two bytes, encoded as UTF-16, and the HotSpot VM string intrinsics to use
UTF-16 encoding.
Tiered Compilation
Tiered compilation, introduced in Java SE 7, brings client VM startup speeds to the server
VM. Without tired compilation, a server VM uses the interpreter to collect profiling information
5-1
Chapter 5
Tiered Compilation
about methods that is sent to the compiler. With tiered compilation, the server VM also
uses the client compiler to generate compiled versions of methods that collect profiling
information about themselves. The compiled code is substantially faster than the
interpreter, and the program executes with greater performance during the profiling
phase. Often, startup is faster than the client VM startup speed because the final code
produced by the server compiler might be available during the early stages of
application initialization. Tiered compilation can also achieve better peak performance
than a regular server VM, because, the faster profiling phase allows a longer period of
profiling, which can yield better optimization.
Tiered compilation is enabled by default for the server VM. The 64-bit mode and
Compressed Ordinary Object Pointer are supported. You can disable tiered
compilation by using the -XX:-TieredCompilation flag with the java command.
To accommodate the additional profiling code that is generated with tiered compilation,
the default size of code cache is multiplied by 5x. To organize and manage the larger
space effectively, segmented code cache is used.
5-2
Chapter 5
Compressed Ordinary Object Pointer
Escape Analysis
Escape analysis is a technique by which the Java HotSpot Server Compiler can analyze the
scope of a new object's uses and decide whether to allocate the object on the Java heap.
Escape analysis is supported and enabled by default in Java SE 6u23 and later.
5-3
Chapter 5
Escape Analysis
The Java HotSpot Server Compiler implements the flow-insensitive escape analysis
algorithm described in:
An object's escape state, based on escape analysis, can be one of the following
states:
• GlobalEscape: The object escapes the method and thread. For example, an object
stored in a static field, stored in a field of an escaped object, or returned as the
result of the current method.
• ArgEscape: The object is passed as an argument or referenced by an argument
but does not globally escape during a call. This state is determined by analyzing
the bytecode of the called method.
• NoEscape: The object is a scalar replaceable object, which means that its
allocation could be removed from generated code.
After escape analysis, the server compiler eliminates the scalar replaceable object
allocations and the associated locks from generated code. The server compiler also
eliminates locks for objects that do not globally escape. It does not replace a heap
allocation with a stack allocation for objects that do not globally escape.
The following examples describe some scenarios for escape analysis:
• The server compiler might eliminate certain object allocations. For example, a
method makes a defensive copy of an object and returns the copy to the caller.
5-4
Chapter 5
Escape Analysis
The method makes a copy to prevent modification of the original object by the caller. If
the compiler determines that the getPerson method is being invoked in a loop, then the
compiler inlines that method. By using escape analysis, when the compiler determines
that the original object is never modified, the compiler can optimize and eliminate the call
to make a copy.
• The server compiler might eliminate synchronization blocks (lock elision) if it determines
that an object is thread local. For example, methods of classes such as StringBuffer
and Vector are synchronized because they can be accessed by different threads.
However, in most scenarios, they are used in a thread local manner. In cases where the
usage is thread local, the compiler can optimize and remove the synchronization blocks.
5-5
6
JVM Constants API
The JVM Constants API is defined in the package java.lang.constants, which contains the
nominal descriptors of various types of loadable constants. These nominal descriptors are
useful for applications that manipulate class files and compile-time or link-time program
analysis tools.
A nominal descriptor is not the value of a loadable constant but a description of its value,
which can be reconstituted given a class loading context. A loadable constant is a constant
pool entry that can be pushed onto the operand stack or can appear in the static argument
list of a bootstrap method for the invokedynamic instruction. The operand stack is where JVM
instructions get their input and store their output. Every Java class file has a constant pool,
which contains several kinds of constants, ranging from numeric literals known at compile-
time to method and field references that must be resolved at run-time.
The issue with working with non-nominal loadable constants, such as a Class objects, whose
references are resolved at run-time, is that these references depend on the correctness and
consistency of the class loading context. Class loading may have side effects, such as
running code that you don't want run and throwing access-related and out-of-memory
exceptions, which you can avoid with nominal descriptions. In addition, class loading may not
be possible at all.
See the package java.lang.constant.
6-1
7
Support for Non-Java Languages
This chapter describes the Non-Java Language features in the Java Virtual Machine.
Topics:
• Introduction to Non-Java Language Features
• Static and Dynamic Typing
• The Challenge of Compiling Dynamically-Typed Languages
• The invokedynamic Instruction
7-1
Chapter 7
Static and Dynamic Typing
import java.util.Date;
#!/usr/bin/env ruby
require 'date'
In the example, every name is introduced without a type declaration. The main
program is not located inside a holder type (the Java class HelloWorld). The Ruby
equivalent of the Java for loop is inside the dynamic type ARGV variable. The body of
7-2
Chapter 7
The Challenge of Compiling Dynamically-Typed Languages
the loop is contained in a block called a closure, which is a common feature in dynamic
languages.
a = "40"
b = a + 2
def addtwo(a, b)
a + b;
end
Suppose your organization is implementing a compiler and runtime system for the
programming language in which the method addtwo is written. In a strongly-typed language,
whether typed statically or dynamically, the behavior of + (the addition operator) depends on
the operand types. A compiler for a statically-typed language chooses the appropriate
implementation of + based on the static types of a and b. For example, a Java compiler
implements + with the iadd JVM instruction if the types of a and b are int. The addition
operator is compiled to a method call because the JVM iadd instruction requires the operand
types to be statically known.
A compiler for a dynamically-typed language must defer the choice until runtime. The
statement a + b is compiled as the method call +(a, b), where + is the method name. A
method named + is permitted in the JVM but not in the Java programming language. If the
runtime system for the dynamically-typed language is able to identify that a and b are
variables of integer type, then the runtime system would prefer to call an implementation of +
that is specialized for integer types rather than arbitrary object types.
7-3
Chapter 7
The Challenge of Compiling Dynamically-Typed Languages
In Java SE 7 and later, the invokedynamic instruction enables the runtime system to
customize the linkage between a call site and a method implementation. In this
example, the invokedynamic call site is +. An invokedynamic call site is linked to a
method by means of a bootstrap method, which is a method specified by the compiler
for the dynamically-typed language that is called once by the JVM to link the site.
Assuming the compiler emitted an invokedynamic instruction that invokes +, and
assuming that the runtime system knows about the method adder(Integer,Integer),
the runtime can link the invokedynamic call site to the adder method as follows:
IntegerOps.java
class IntegerOps {
Example.java
import java.util.*;
import java.lang.invoke.*;
import static java.lang.invoke.MethodType.*;
import static java.lang.invoke.MethodHandles.*;
class Example {
MethodHandle mh =
callerClass.findStatic(
Example.class,
"IntegerOps.adder",
MethodType.methodType(Integer.class, Integer.class,
Integer.class));
if (!dynMethodType.equals(mh.type())) {
mh = mh.asType(dynMethodType);
}
7-4
Chapter 7
The invokedynamic Instruction
In this example, the IntegerOps class belongs to the library that accompanies runtime system
for the dynamically-typed language.
The Example.mybsm method is a bootstrap method that links the invokedynamic call site to
the adder method.
The callerClass object is a lookup object, which is a factory for creating method handles.
Note: This bootstrap method links an invokedynamic call site to only the code that is defined
in the adder method. It assumes that the arguments given to the invokedynamic call site are
Integer objects. A bootstrap method requires additional code to properly link invokedynamic
call sites to the appropriate code to execute if the parameters of the bootstrap method (in this
example, callerClass, dynMethodName, and dynMethodType) vary.
7-5
Chapter 7
The invokedynamic Instruction
using the Example.mybsm bootstrap method. The adder method and mybsm method are
defined in The Challenge of Compiling Dynamically Typed Languages (line breaks
have been added for clarity):
invokedynamic InvokeDynamic
REF_invokeStatic:
Example.mybsm:
"(Ljava/lang/invoke/MethodHandles/Lookup;
Ljava/lang/String;
Ljava/lang/invoke/MethodType;)
Ljava/lang/invoke/CallSite;":
+:
"(Ljava/lang/Integer;
Ljava/lang/Integer;)
Ljava/lang/Integer;";
Note:
The bytecode examples use the syntax of the ASM Java bytecode
manipulation and analysis framework.
7-6
Chapter 7
The invokedynamic Instruction
bootstrap method. In principle, the name and extra arguments are redundant because
each call site could be given its own unique bootstrap method. However, such a practice
is likely to produce large class files and constant pools
See The Challenge of Compiling Dynamically Typed Languages for an example of a
bootstrap method.
// ...
The constant pool entry for the invokedynamic instruction in this example contains the
following values:
• CONSTANT_InvokeDynamic tag
• Unsigned short of value 0
• Constant pool index #234.
The value, 0, refers to the first bootstrap method specifier in the array of specifiers that are
stored in the BootstrapMethods attribute. Bootstrap method specifiers are not in the constant
7-7
Chapter 7
The invokedynamic Instruction
pool table. They are contained in this separate array of specifiers. Each bootstrap
method specifier contains an index to a CONSTANT_MethodHandle constant pool entry,
which is the bootstrap method itself.
The following example shows an excerpt from the same constant pool that shows the
BootstrapMethods attribute, which contains the array of bootstrap method specifiers:
[3] { // Attributes
// ...
The constant pool entry for the bootstrap method mybsm method handle contains the
following values:
• CONSTANT_MethodHandle tag
• Unsigned byte of value 6
• Constant pool index #232.
The value, 6, is the REF_invokeStatic subtag. See, Using the invokedynamic
Instruction, for more information about this subtag.
bipush 40;
invokestatic Method java/lang/Integer.valueOf:"(I)Ljava/lang/
Integer;";
iconst_2;
invokestatic Method java/lang/Integer.valueOf:"(I)Ljava/lang/
Integer;";
invokedynamic InvokeDynamic
REF_invokeStatic:
Example.mybsm:
"(Ljava/lang/invoke/MethodHandles/Lookup;
Ljava/lang/String;
Ljava/lang/invoke/MethodType;)
7-8
Chapter 7
The invokedynamic Instruction
Ljava/lang/invoke/CallSite;":
+:
"(Ljava/lang/Integer;
Ljava/lang/Integer;)
Ljava/lang/Integer;";
The first four instructions put the integers 40 and 2 in the stack and boxes them in the
java.lang.Integer wrapper type. The fifth instruction invokes a dynamic method. This
instruction refers to a constant pool entry with a CONSTANT_InvokeDynamic tag:
REF_invokeStatic:
Example.mybsm:
"(Ljava/lang/invoke/MethodHandles/Lookup;
Ljava/lang/String;
Ljava/lang/invoke/MethodType;)
Ljava/lang/invoke/CallSite;":
+:
"(Ljava/lang/Integer;
Ljava/lang/Integer;)
Ljava/lang/Integer;";
• The first two bytes form a reference to a CONSTANT_MethodHandle entry that references a
bootstrap method specifier:
REF_invokeStatic:
Example.mybsm:
"(Ljava/lang/invoke/MethodHandles/Lookup;
Ljava/lang/String;
Ljava/lang/invoke/MethodType;)
Ljava/lang/invoke/CallSite;"
This reference to a bootstrap method specifier is not in the constant pool table. It is
contained in a separate array defined by a class file attribute named BootstrapMethods.
The bootstrap method specifier contains an index to a CONSTANT_MethodHandle constant
pool entry, which is the bootstrap method itself.
Three bytes follow this CONSTANT_MethodHandle constant pool entry:
– The first byte is the REF_invokeStatic subtag. This means that this bootstrap
method will create a method handle for a static method; note that this bootstrap
method is linking the dynamic call site with the static Java adder method.
– The next two bytes form a CONSTANT_Methodref entry that represents the method for
which the method handle is to be created:
Example.mybsm:
"(Ljava/lang/invoke/MethodHandles/Lookup;
Ljava/lang/String;
7-9
Chapter 7
The invokedynamic Instruction
Ljava/lang/invoke/MethodType;)
Ljava/lang/invoke/CallSite;"
+:
"(Ljava/lang/Integer;
Ljava/lang/Integer;)
Ljava/lang/Integer;"
This constant pool entry specifies the method name (+), the argument types (two
Integer instances), and return type of the dynamic call site (Integer).
In this example, the dynamic call site is presented with boxed integer values, which
exactly match the type of the eventual target, the adder method. In practice, the
argument and return types don’t need to exactly match. For example, the
invokedynamic instruction could pass either or both of its operands on the JVM stack
as primitive int values. Either or both operands could be untyped Object values. The
invokedynamic instruction could receive its result as a primitive int value, or an
untyped Object value. In any case, the dynMethodType argument to mybsm accurately
describes the method type that is required by the invokedynamic instruction.
The adder method could be given primitive or untyped arguments or return values.
The bootstrap method is responsible for making up any difference between the
dynMethodType and the type of the adder method. As shown in the code, this is easily
done with an asType call on the target method.
7-10
8
Signal Chaining
Signal chaining enables you to write applications that need to install their own signal
handlers. This facility is available on Linux and macOS.
The signal chaining facility has the following features:
• Support for preinstalled signal handlers when you create Oracle’s HotSpot Virtual
Machine.
When the HotSpot VM is created, the signal handlers for signals that are used by the
HotSpot VM are saved. During execution, when any of these signals are raised and are
not to be targeted at the HotSpot VM, the preinstalled handlers are invoked. In other
words, preinstalled signal handlers are chained behind the HotSpot VM handlers for
these signals.
• Support for the signal handlers that are installed after you create the HotSpot VM, either
inside the Java Native Interface code or from another native thread.
Your application can link and load the libjsig.so shared library before the libc/
libthread/libpthread library. This library ensures that calls to sigaction() are
intercepted and don’t replace the signal handlers that are used by the HotSpot VM, if the
handlers conflict with the signal handlers that are already installed by HotSpot VM.
Instead, these calls save the new signal handlers. The new signal handlers are chained
behind the HotSpot VM signal handlers for the signals. During execution, when any of
these signals are raised and are not targeted at the HotSpot VM, the preinstalled
handlers are invoked.
If support for signal handler installation after the creation of the VM is not required, then
the libjsig.so shared library is not needed.
To enable signal chaining, perform one of the following procedures to use the libjsig.so
shared library:
– Link the libjsig.so shared library with the application that creates or embeds the
HotSpot VM:
* C shell (csh):
The interposed sigaction() call returns the saved signal handlers, not the signal
handlers installed by the HotSpot VM and seen by the operating system.
8-1
Chapter 8
Note:
The SIGQUIT, SIGTERM, SIGINT, and SIGHUP signals cannot be chained. If the
application must handle these signals, then consider using the —Xrs option.
Note:
The library file name on macOS is libjsig.dylib not libjsig.so as it is on
Linux.
8-2
9
Native Memory Tracking
This chapter describes the Native Memory Tracking (NMT) feature. NMT is a Java Hotspot
VM feature that tracks internal memory usage for a HotSpot VM. You can access NMT data
by using the jcmd utility. NMT does not track memory allocations for third-party native code
and Oracle Java Development Kit (JDK) class libraries. NMT does not include NMT MBean in
HotSpot for Java Mission Control (JMC).
Topics:
• Key Features
• Using Native Memory Tracking
– Enabling NMT
– Accessing NMT Data using jcmd
• Obtaining NMT Data at VM Exit
Key Features
When you use Native Memory Tracking with jcmd, you can track Java Virtual Machine (JVM)
or HotSpot VM memory usage at different levels. NMT tracks only the memory that the JVM
or HotSpot VM uses, not the user's native memory. NMT doesn't give complete information
for the memory used by the class data sharing (CDS) archive.
NMT for HotSpot VM is turned off by default. You can turn on NMT by using the JVM
command-line option. See java in the Java Development Kit Tool Specifications for
information about advanced runtime options.
You can access NMT using the jcmd utility. See Use jcmd to Access NMT Data. You can stop
NMT by using the jcmd utility, but you can't start or restart NMT by using the jcmd utilty.
Enabling NMT
To enable NMT, use the following command-line options:
-XX:NativeMemoryTracking=[off | summary | detail]
9-1
Chapter 9
Obtaining NMT Data at VM Exit
Note:
Enabling NMT causes a 5% -10% performance overhead.
See Native Memory Tracking in the Java Platform, Standard Edition Troubleshooting
Guide for information about how to monitor VM internal memory allocations and
diagnose VM memory leaks.
9-2
10
DTrace Probes in HotSpot VM
This chapter describes DTrace support in Oracle’s HotSpot VM. The hotspot and hotspot_jni
providers let you access probes that you can use to monitor the Java application that is
running together with the internal state and activities of the Java Virtual Machine (JVM). All of
the probes are USDT probes and you can access them by using the process-id of the JVM
process.
Topics:
• Using the hotspot Provider
– VM Lifecycle Probes
– Thread Lifecycle Probes
– Classloading Probes
– Garbage Collection Probes
– Method Compilation Probes
– Monitor Probes
– Application Tracking Probes
• Using the hotspot_jni Provider
• Sample DTrace Probes
VM Lifecycle Probes
The following probes are available for tracking VM lifecycle activities. None have any
arguments.
10-1
Chapter 10
Using the hotspot Provider
Probe Description
vm-init-begin Probe that starts when the VM initialization begins
vm-init-end Probe that starts when the VM initialization finishes, and
the VM is ready to start running application code
vm-shutdown Probe that starts as the VM is shuts down due to
program termination or an error
Probe Description
thread-start Probe that starts when a thread starts.
thread-stop Probe that starts when the thread has completed.
The following argument are available for the thread lifecycle probes:
Classloading Probes
The following probes are available for tracking class loading and unloading activity.
Probe Description
class-loaded Probe that fires when a class is loaded
class-unloaded Probe that fires when a class is unloaded from the
system
10-2
Chapter 10
Using the hotspot Provider
Probe Description
gc-begin Probe that starts when a system-wide collection starts.
The one argument available for this probe, (arg[0]), is
a boolean value that indicates whether to perform a Full
GC.
gc-end Probe that starts when a system-wide collection is
completed. No arguments.
mem-pool-gc-begin Probe that starts when an individual memory pool is
collected.
mem-pool-gc-end Probe that starts after an individual memory pool is
collected.
The following arguments are available for the memory pool probes:
10-3
Chapter 10
Using the hotspot Provider
Probe Description
method-compile-begin Probe that starts when the method compilation begins.
method-compile-end Probe that starts when method compilation is
completed. In addition to the following arguments, the
argv[8] argument is a boolean value that indicates
whether the compilation was successful.
The following arguments are available for the method compilation probes:
The following probes are available when compiled methods are installed for execution
or uninstalled:
Probe Description
compiled-method-load Probe that starts when a compiled method is installed.
The additional argument, argv[6] contains a pointer to
the compiled code, and the argv[7] is the size of the
compiled code.
compiled-method-unload Probe that starts when a compiled method is uninstalled.
The following arguments are available for the compiled method loading probe:
10-4
Chapter 10
Using the hotspot Provider
Monitor Probes
When your Java application runs, threads enter and exit monitors, wait on monitors, and
perform notifications. Probes are available for all wait and notification events, and for
contended monitor entry and exit events.
A contended monitor entry occurs when a thread attempts to enter a monitor while another
thread is in the monitor. A contended monitor exit event occurs when a thread leaves a
monitor while other threads are waiting to enter to the monitor. The contended monitor entry
and contended monitor exit events might not match each other in relation to the thread that
encounters these events, athough a contended exit from one thread is expected to match up
to a contended enter on another thread (the thread waiting to enter the monitor).
Monitor events provide the thread ID, a monitor ID, and the type of the class of the object as
arguments. The thread ID and the class type can map back to the Java program, while the
monitor ID can provide matching information between probe firings.
The existence of these probes in the VM degrades performance and they start only when the
-XX:+ExtendedDTraceProbes flag is set on the Java command line. This flag is turned on and
off dynamically at runtime by using the jinfo utility.
If the flag is off, the monitor probes are present in the probe listing that is obtainable from
Dtrace, but the probes remain dormant and don’t start. Removal of this restriction is planned
for future releases of the VM, and these probes will be enabled with no impact to
performance.
The following probes are available for monitoring events:
Probe Description
monitor-contended-enter Probe that starts when a thread attempts to enter a
contended monitor
monitor-contended-entered Probe that starts when a thread successfully enters the
contended monitor
monitor-contended-exit Probe that starts when a thread leaves a monitor and
other threads are waiting to enter
monitor-wait Probe that starts when a thread begins a wait on a
monitor by using the Object.wait(). The additional
argument, args[4] is a long value that indicates the
timeout being used.
monitor-waited Probe that starts when a thread completes an
Object.wait() action.
10-5
Chapter 10
Using the hotspot Provider
Probe Description
monitor-notify Probe that starts when a thread calls
Object.notify() to notify waiters on a monitor.
monitor-notifyAll Probe that starts when a thread calls
Object.notifyAll() to notify waiters on a monitor.
Probe Description
method-entry Probe that starts when a method is being entered.
method-return Probe that starts when a method returns, either normally
or due to an exception.
The following arguments are available for the method entry and exit:
10-6
Chapter 10
Using the hotspot_jni Provider
Probe Description
object-alloc Probe that starts when any object is allocated, provided
that the ExtendedDTraceProbes flag is enabled.
The following arguments are available for the object allocation probe:
10-7
Chapter 10
Sample DTrace Probes
10-8
Chapter 10
Sample DTrace Probes
provider hotspot_jni {
probe AllocObject-entry(void*, void*);
probe AllocObject-return(void*);
probe AttachCurrentThreadAsDaemon-entry(void*, void**, void*);
probe AttachCurrentThreadAsDaemon-return(uint32_t);
probe AttachCurrentThread-entry(void*, void**, void*);
probe AttachCurrentThread-return(uint32_t);
probe CallBooleanMethodA-entry(void*, void*, uintptr_t);
probe CallBooleanMethodA-return(uintptr_t);
probe CallBooleanMethod-entry(void*, void*, uintptr_t);
probe CallBooleanMethod-return(uintptr_t);
probe CallBooleanMethodV-entry(void*, void*, uintptr_t);
probe CallBooleanMethodV-return(uintptr_t);
probe CallByteMethodA-entry(void*, void*, uintptr_t);
probe CallByteMethodA-return(char);
probe CallByteMethod-entry(void*, void*, uintptr_t);
probe CallByteMethod-return(char);
probe CallByteMethodV-entry(void*, void*, uintptr_t);
probe CallByteMethodV-return(char);
probe CallCharMethodA-entry(void*, void*, uintptr_t);
probe CallCharMethodA-return(uint16_t);
probe CallCharMethod-entry(void*, void*, uintptr_t);
probe CallCharMethod-return(uint16_t);
probe CallCharMethodV-entry(void*, void*, uintptr_t);
probe CallCharMethodV-return(uint16_t);
probe CallDoubleMethodA-entry(void*, void*, uintptr_t);
probe CallDoubleMethodA-return(double);
probe CallDoubleMethod-entry(void*, void*, uintptr_t);
probe CallDoubleMethod-return(double);
probe CallDoubleMethodV-entry(void*, void*, uintptr_t);
probe CallDoubleMethodV-return(double);
probe CallFloatMethodA-entry(void*, void*, uintptr_t);
probe CallFloatMethodA-return(float);
probe CallFloatMethod-entry(void*, void*, uintptr_t);
probe CallFloatMethod-return(float);
probe CallFloatMethodV-entry(void*, void*, uintptr_t);
10-9
Chapter 10
Sample DTrace Probes
probe CallFloatMethodV-return(float);
probe CallIntMethodA-entry(void*, void*, uintptr_t);
probe CallIntMethodA-return(uint32_t);
probe CallIntMethod-entry(void*, void*, uintptr_t);
probe CallIntMethod-return(uint32_t);
probe CallIntMethodV-entry(void*, void*, uintptr_t);
probe CallIntMethodV-return(uint32_t);
probe CallLongMethodA-entry(void*, void*, uintptr_t);
probe CallLongMethodA-return(uintptr_t);
probe CallLongMethod-entry(void*, void*, uintptr_t);
probe CallLongMethod-return(uintptr_t);
probe CallLongMethodV-entry(void*, void*, uintptr_t);
probe CallLongMethodV-return(uintptr_t);
probe CallNonvirtualBooleanMethodA-entry(void*, void*, void*,
uintptr_t);
probe CallNonvirtualBooleanMethodA-return(uintptr_t);
probe CallNonvirtualBooleanMethod-entry(void*, void*, void*,
uintptr_t);
probe CallNonvirtualBooleanMethod-return(uintptr_t);
probe CallNonvirtualBooleanMethodV-entry(void*, void*, void*,
uintptr_t);
probe CallNonvirtualBooleanMethodV-return(uintptr_t);
probe CallNonvirtualByteMethodA-entry(void*, void*, void*,
uintptr_t);
probe CallNonvirtualByteMethodA-return(char);
probe CallNonvirtualByteMethod-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualByteMethod-return(char);
probe CallNonvirtualByteMethodV-entry(void*, void*, void*,
uintptr_t);
probe CallNonvirtualByteMethodV-return(char);
probe CallNonvirtualCharMethodA-entry(void*, void*, void*,
uintptr_t);
probe CallNonvirtualCharMethodA-return(uint16_t);
probe CallNonvirtualCharMethod-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualCharMethod-return(uint16_t);
probe CallNonvirtualCharMethodV-entry(void*, void*, void*,
uintptr_t);
probe CallNonvirtualCharMethodV-return(uint16_t);
probe CallNonvirtualDoubleMethodA-entry(void*, void*, void*,
uintptr_t);
probe CallNonvirtualDoubleMethodA-return(double);
probe CallNonvirtualDoubleMethod-entry(void*, void*, void*,
uintptr_t);
probe CallNonvirtualDoubleMethod-return(double);
probe CallNonvirtualDoubleMethodV-entry(void*, void*, void*,
uintptr_t);
probe CallNonvirtualDoubleMethodV-return(double);
probe CallNonvirtualFloatMethodA-entry(void*, void*, void*,
uintptr_t);
probe CallNonvirtualFloatMethodA-return(float);
probe CallNonvirtualFloatMethod-entry(void*, void*, void*,
uintptr_t);
probe CallNonvirtualFloatMethod-return(float);
probe CallNonvirtualFloatMethodV-entry(void*, void*, void*,
uintptr_t);
10-10
Chapter 10
Sample DTrace Probes
probe CallNonvirtualFloatMethodV-return(float);
probe CallNonvirtualIntMethodA-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualIntMethodA-return(uint32_t);
probe CallNonvirtualIntMethod-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualIntMethod-return(uint3t);
probe CallNonvirtualIntMethodV-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualIntMethodV-return(uint32_t);
probe CallNonvirtualLongMethodA-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualLongMethodA-return(uintptr_t);
probe CallNonvirtualLongMethod-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualLongMethod-return(uintptr_t);
probe CallNonvirtualLongMethodV-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualLongMethodV-return(uintptr_t);
probe CallNonvirtualObjectMethodA-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualObjectMethodA-return(void*);
probe CallNonvirtualObjectMethod-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualObjectMethod-return(void*);
probe CallNonvirtualObjectMethodV-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualObjectMethodV-return(void*);
probe CallNonvirtualShortMethodA-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualShortMethodA-return(uint16_t);
probe CallNonvirtualShortMethod-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualShortMethod-return(uint16_t);
probe CallNonvirtualShortMethodV-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualShortMethodV-return(uint16_t);
probe CallNonvirtualVoidMethodA-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualVoidMethodA-return();
probe CallNonvirtualVoidMethod-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualVoidMethod-return();
probe CallNonvirtualVoidMethodV-entry(void*, void*, void*, uintptr_t);
probe CallNonvirtualVoidMethodV-return();
probe CallObjectMethodA-entry(void*, void*, uintptr_t);
probe CallObjectMethodA-return(void*);
probe CallObjectMethod-entry(void*, void*, uintptr_t);
probe CallObjectMethod-return(void*);
probe CallObjectMethodV-entry(void*, void*, uintptr_t);
probe CallObjectMethodV-return(void*);
probe CallShortMethodA-entry(void*, void*, uintptr_t);
probe CallShortMethodA-return(uint16_t);
probe CallShortMethod-entry(void*, void*, uintptr_t);
probe CallShortMethod-return(uint16_t);
probe CallShortMethodV-entry(void*, void*, uintptr_t);
probe CallShortMethodV-return(uint16_t);
probe CallStaticBooleanMethodA-entry(void*, void*, uintptr_t);
probe CallStaticBooleanMethodA-return(uintptr_t);
probe CallStaticBooleanMethod-entry(void*, void*, uintptr_t);
probe CallStaticBooleanMethod-return(uintptr_t);
probe CallStaticBooleanMethodV-entry(void*, void*, uintptr_t);
probe CallStaticBooleanMethodV-return(uintptr_t);
probe CallStaticByteMethodA-entry(void*, void*, uintptr_t);
probe CallStaticByteMethodA-return(char);
probe CallStaticByteMethod-entry(void*, void*, uintptr_t);
probe CallStaticByteMethod-return(char);
probe CallStaticByteMethodV-entry(void*, void*, uintptr_t);
probe CallStaticByteMethodV-return(char);
10-11
Chapter 10
Sample DTrace Probes
10-12
Chapter 10
Sample DTrace Probes
probe CreateJavaVM-return(uint32_t);
probe DefineClass-entry(void*, const char*, void*, char, uintptr_t);
probe DefineClass-return(void*);
probe DeleteGlobalRef-entry(void*, void*);
probe DeleteGlobalRef-return();
probe DeleteLocalRef-entry(void*, void*);
probe DeleteLocalRef-return();
probe DeleteWeakGlobalRef-entry(void*, void*);
probe DeleteWeakGlobalRef-return();
probe DestroyJavaVM-entry(void*);
probe DestroyJavaVM-return(uint32_t);
probe DetachCurrentThread-entry(void*);
probe DetachCurrentThread-return(uint32_t);
probe EnsureLocalCapacity-entry(void*, uint32_t);
probe EnsureLocalCapacity-return(uint32_t);
probe ExceptionCheck-entry(void*);
probe ExceptionCheck-return(uintptr_t);
probe ExceptionClear-entry(void*);
probe ExceptionClear-return();
probe ExceptionDescribe-entry(void*);
probe ExceptionDescribe-return();
probe ExceptionOccurred-entry(void*);
probe ExceptionOccurred-return(void*);
probe FatalError-entry(void* env, const char*);
probe FindClass-entry(void*, const char*);
probe FindClass-return(void*);
probe FromReflectedField-entry(void*, void*);
probe FromReflectedField-return(uintptr_t);
probe FromReflectedMethod-entry(void*, void*);
probe FromReflectedMethod-return(uintptr_t);
probe GetArrayLength-entry(void*, void*);
probe GetArrayLength-return(uintptr_t);
probe GetBooleanArrayElements-entry(void*, void*, uintptr_t*);
probe GetBooleanArrayElements-return(uintptr_t*);
probe GetBooleanArrayRegion-entry(void*, void*, uintptr_t, uintptr_t,
uintptr_t*);
probe GetBooleanArrayRegion-return();
probe GetBooleanField-entry(void*, void*, uintptr_t);
probe GetBooleanField-return(uintptr_t);
probe GetByteArrayElements-entry(void*, void*, uintptr_t*);
probe GetByteArrayElements-return(char*);
probe GetByteArrayRegion-entry(void*, void*, uintptr_t, uintptr_t, char*);
probe GetByteArrayRegion-return();
probe GetByteField-entry(void*, void*, uintptr_t);
probe GetByteField-return(char);
probe GetCharArrayElements-entry(void*, void*, uintptr_t*);
probe GetCharArrayElements-return(uint16_t*);
probe GetCharArrayRegion-entry(void*, void*, uintptr_t, uintptr_t,
uint16_t*);
probe GetCharArrayRegion-return();
probe GetCharField-entry(void*, void*, uintptr_t);
probe GetCharField-return(uint16_t);
probe GetCreatedJavaVMs-eintptr_t*);
probe GetCreatedJavaVMs-return(uintptr_t);
probe GetCreateJavaVMs-entry(void*, uintptr_t, uintptr_t*);
10-13
Chapter 10
Sample DTrace Probes
probe GetCreateJavaVMs-return(uint32_t);
probe GetDefaultJavaVMInitArgs-entry(void*);
probe GetDefaultJavaVMInitArgs-return(uint32_t);
probe GetDirectBufferAddress-entry(void*, void*);
probe GetDirectBufferAddress-return(void*);
probe GetDirectBufferCapacity-entry(void*, void*);
probe GetDirectBufferCapacity-return(uintptr_t);
probe GetDoubleArrayElements-entry(void*, void*, uintptr_t*);
probe GetDoubleArrayElements-return(double*);
probe GetDoubleArrayRegion-entry(void*, void*, uintptr_t, uintptr_t,
double*);
probe GetDoubleArrayRegion-return();
probe GetDoubleField-entry(void*, void*, uintptr_t);
probe GetDoubleField-return(double);
probe GetEnv-entry(void*, void*, void*);
probe GetEnv-return(uint32_t);
probe GetFieldID-entry(void*, void*, const char*, const char*);
probe GetFieldID-return(uintptr_t);
probe GetFloatArrayElements-entry(void*, void*, uintptr_t*);
probe GetFloatArrayElements-return(float*);
probe GetFloatArrayRegion-entry(void*, void*, uintptr_t, uintptr_t,
float*);
probe GetFloatArrayRegion-return();
probe GetFloatField-entry(void*, void*, uintptr_t);
probe GetFloatField-return(float);
probe GetIntArrayElements-entry(void*, void*, uintptr_t*);
probe GetIntArrayElements-return(uint32_t*);
probe GetIntArrayRegion-entry(void*, void*, uintptr_t, uintptr_t,
uint32_t*);
probe GetIntArrayRegion-return();
probe GetIntField-entry(void*, void*, uintptr_t);
probe GetIntField-return(uint32_t);
probe GetJavaVM-entry(void*, void**);
probe GetJavaVM-return(uint32_t);
probe GetLongArrayElements-entry(void*, void*, uintptr_t*);
probe GetLongArrayElements-return(uintptr_t*);
probe GetLongArrayRegion-entry(void*, void*, uintptr_t, uintptr_t,
uintptr_t*);
probe GetLongArrayRegion-return();
probe GetLongField-entry(void*, void*, uintptr_t);
probe GetLongField-return(uintptr_t);
probe GetMethodID-entry(void*, void*, const char*, const char*);
probe GetMethodID-return(uintptr_t);
probe GetObjectArrayElement-entry(void*, void*, uintptr_t);
probe GetObjectArrayElement-return(void*);
probe GetObjectClass-entry(void*, void*);
probe GetObjectClass-return(void*);
probe GetObjectField-entry(void*, void*, uintptr_t);
probe GetObjectField-return(void*);
probe GetObjectRefType-entry(void*, void*);
probe GetObjectRefType-return(void*);
probe GetPrimitiveArrayCritical-entry(void*, void*, uintptr_t*);
probe GetPrimitiveArrayCritical-return(void*);
probe GetShortArrayElements-entry(void*, void*, uintptr_t*);
probe GetShortArrayElements-return(uint16_t*);
10-14
Chapter 10
Sample DTrace Probes
10-15
Chapter 10
Sample DTrace Probes
10-16
Chapter 10
Sample DTrace Probes
probe ReleaseFloatArrayElements-return();
probe ReleaseIntArrayElements-entry(void*, void*, uint32_t*, uint32_t);
probe ReleaseIntArrayElements-return();
probe ReleaseLongArrayElements-entry(void*, void*, uintptr_t*, uint32_t);
probe ReleaseLongArrayElements-return();
probe ReleaseObjectArrayElements-entry(void*, void*, void**, uint32_t);
probe ReleaseObjectArrayElements-return();
probe Releasey(void*, void*, void*, uint32_t);
probe ReleasePrimitiveArrayCritical-return();
probe ReleaseShortArrayElements-entry(void*, void*, uint16_t*, uint32_t);
probe ReleaseShortArrayElements-return();
probe ReleaseStringChars-entry(void*, void*, const uint16_t*);
probe ReleaseStringChars-return();
probe ReleaseStringCritical-entry(void*, void*, const uint16_t*);
probe ReleaseStringCritical-return();
probe ReleaseStringUTFChars-entry(void*, void*, const char*);
probe ReleaseStringUTFChars-return();
probe SetBooleanArrayRegion-entry(void*, void*, uintptr_t, uintptr_t,
const uintptr_t*);
probe SetBooleanArrayRegion-return();
probe SetBooleanField-entry(void*, void*, uintptr_t, uintptr_t);
probe SetBooleanField-return();
probe SetByteArrayRegion-entry(void*, void*, uintptr_t, uintptr_t, const
char*);
probe SetByteArrayRegion-return();
probe SetByteField-entry(void*, void*, uintptr_t, char);
probe SetByteField-return();
probe SetCharArrayRegion-entry(void*, void*, uintptr_t, uintptr_t, const
uint16_t*);
probe SetCharArrayRegion-return();
probe SetCharField-entry(void*, void*, uintptr_t, uint16_t);
probe SetCharField-return();
probe SetDoubleArrayRegion-entry(void*, void*, uintptr_t, uintptr_t, const
double*);
probe SetDoubleArrayRegion-return();
probe SetDoubleField-entry(void*, void*, uintptr_t, double);
probe SetDoubleField-return();
probe SetFloatArrayRegion-entry(void*, void*, uintptr_t, uintptr_t, const
float*);
probe SetFloatArrayRegion-return();
probe SetFloatField-entry(void*, void*, uintptr_t, float);
probe SetFloatField-return();
probe SetIntArrayRegion-entry(void*, void*, uintptr_t, uintptr_t, const
uint32_t*);
probe SetIntArrayRegion-return();
probe SetIntField-entry(void*, void*, uintptr_t, uint32_t);
probe SetIntField-return();
probe SetLongArrayRegion-entry(void*, void*, uintptr_t, uintptr_t, const
uintptr_t*);
probe SetLongArrayRegion-return();
probe SetLongField-entry(void*, void*, uintptr_t, uintptr_t);
probe SetLongField-return();
probe SetObjectArrayElement-entry(void*, void*, uintptr_t, void*);
probe SetObjectArrayElement-return();
probe SetObjectField-entry(void*, void*, uintptr_t, void*);
10-17
Chapter 10
Sample DTrace Probes
probe SetObjectField-return();
probe SetShortArrayRegion-entry(void*, void*, uintptr_t, uintptr_t,
const uint16_t*);
probe SetShortArrayRegion-return();
probe SetShortField-entry(void*, void*, uintptr_t, uint16_t);
probe SetShortField-return();
probe SetStaticBooleanField-entry(void*, void*, uintptr_t,
uintptr_t);
probe SetStaticBooleanField-return();
probe SetStaticByteField-entry(void*, void*, uintptr_t, char);
probe SetStaticByteField-return();
probe SetStaticCharField-entry(void*, void*, uintptr_t, uint16_t);
probe SetStaticCharField-return();
probe SetStaticDoubleField-entry(void*, void*, uintptr_t, double);
probe SetStaticDoubleField-return();
probe SetStaticFloatField-entry(void*, void*, uintptr_t, float);
probe SetStaticFloatField-return();
probe SetStaticIntField-entry(void*, void*, uintptr_t, uint32_t);
probe SetStaticIntField-return();
probe SetStaticLongField-entry(void*, void*, uintptr_t, uintptr_t);
probe SetStaticLongField-return();
probe SetStaticObjectField-entry(void*, void*, uintptr_t, void*);
probe SetStaticObjectField-return();
probe SetStaticShortField-entry(void*, void*, uintptr_t, uint16_t);
probe SetStaticShortField-return();
probe Throw-entry(void*, void*);
probe ThrowNew-entry(void*, void*, const char*);
probe ThrowNew-return(uint32_t);
probe Throw-return(uint32_t);
probe ToReflectedField-entry(void*, void*, uintptr_t, uintptr_t);
probe ToReflectedField-return(void*);
probe ToReflectedMethod-entry(void*, void*, uintptr_t, uintptr_t);
probe ToReflectedMethod-return(void*);
probe UnregisterNatives-entry(void*, void*);
probe UnregisterNatives-return(uint32_t);
};
10-18
11
Fatal Error Reporting
Fatal errors are errors such as native memory exhaustion, memory access errors, or explicit
signals directed to the process. Fatal errors can be triggered by native code within the
application (for example, developer-written Java Native Interface (JNI) code), by third-party
native libraries that the are used by application or the JVM, or by native code in the JVM. If a
fatal error causes the process that is hosting the JVM to terminate, the JVM gathers
information about the error and writes a crash report.
The JVM tries to identify the nature and location of the error. If possible, the JVM writes
detailed information about the state of the JVM and the process, at the time of the crash. The
details that are available can depend on the platform and the nature of the crash. The
information that is provided by this error-reporting mechanism lets you debug your application
more easily and efficiently, and helps you identify issues in third-party code. When an error
message indicates a problem in the JVM code, you can submit a more accurate and helpful
bug report. In some cases, crash report generation causes secondary errors that prevent full
details from being reported.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f0f159f857d, pid=18240, tid=18245
#
# JRE version: Java(TM) SE Runtime Environment (9.0+167) (build 9-ea+167)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (9-ea+167, mixed mode, tiered,
compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# C [libMyApp.so+0x57d] Java_MyApp_readData+0x11
#
# Core dump will be written. Default location: /cores/core.18240)
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
--------------- S U M M A R Y ------------
11-1
Chapter 11
Error Report Example
--------------- T H R E A D ---------------
Stack: [0x00007f10345c0000,0x00007f10346c0000],
sp=0x00007f10346be930, free space=1018k
Native frames: (J=compiled Java code, A=aot compiled Java code,
j=interpreted, Vv=VM code, C=native code)
C [libMyApp.so+0x57d] Java_MyApp_readData+0x11
j MyApp.readData()I+0
j MyApp.main([Ljava/lang/String;)V+15
v ~StubRoutines::call_stub
V [libjvm.so+0x839eea] JavaCalls::call_helper(JavaValue*,
methodHandle const&, JavaCallArguments*, Thread*)+0x47a
V [libjvm.so+0x896fcf] jni_invoke_static(JNIEnv_*, JavaValue*,
_jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*)
[clone .isra.90]+0x21f
V [libjvm.so+0x8a7f1e] jni_CallStaticVoidMethod+0x14e
C [libjli.so+0x4142] JavaMain+0x812
C [libpthread.so.0+0x7e9a] start_thread+0xda
11-2
12
Java Virtual Machine Related Resources
The following related links are related to the JVM.
• java.lang.invoke package documentation
• The Da Vinci Machine Project
Tools
You can control some operating characteristics of the Java HotSpot VM by using command-
line flags. For more information about the Java application launcher, see The java Command
in the Java Development Kit Tool Specifications.
12-1