Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
40934fb4
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
40934fb4
编写于
10月 05, 2013
作者:
S
sla
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
7095fdf5
368ee520
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
374 addition
and
38 deletion
+374
-38
agent/src/share/classes/sun/jvm/hotspot/utilities/AbstractHeapGraphWriter.java
...es/sun/jvm/hotspot/utilities/AbstractHeapGraphWriter.java
+8
-0
agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java
...classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java
+113
-23
test/TEST.groups
test/TEST.groups
+3
-1
test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapProc.java
.../serviceability/sa/jmap-hprof/JMapHProfLargeHeapProc.java
+71
-0
test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java
.../serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java
+146
-0
test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java
...tlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java
+33
-14
未找到文件。
agent/src/share/classes/sun/jvm/hotspot/utilities/AbstractHeapGraphWriter.java
浏览文件 @
40934fb4
...
...
@@ -59,6 +59,7 @@ public abstract class AbstractHeapGraphWriter implements HeapGraphWriter {
public
boolean
doObj
(
Oop
oop
)
{
try
{
writeHeapRecordPrologue
();
if
(
oop
instanceof
TypeArray
)
{
writePrimitiveArray
((
TypeArray
)
oop
);
}
else
if
(
oop
instanceof
ObjArray
)
{
...
...
@@ -97,6 +98,7 @@ public abstract class AbstractHeapGraphWriter implements HeapGraphWriter {
// not-a-Java-visible oop
writeInternalObject
(
oop
);
}
writeHeapRecordEpilogue
();
}
catch
(
IOException
exp
)
{
throw
new
RuntimeException
(
exp
);
}
...
...
@@ -416,6 +418,12 @@ public abstract class AbstractHeapGraphWriter implements HeapGraphWriter {
protected
void
writeHeapFooter
()
throws
IOException
{
}
protected
void
writeHeapRecordPrologue
()
throws
IOException
{
}
protected
void
writeHeapRecordEpilogue
()
throws
IOException
{
}
// HeapVisitor, OopVisitor methods can't throw any non-runtime
// exception. But, derived class write methods (which are called
// from visitor callbacks) may throw IOException. Hence, we throw
...
...
agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java
浏览文件 @
40934fb4
...
...
@@ -44,7 +44,7 @@ import sun.jvm.hotspot.runtime.*;
* WARNING: This format is still under development, and is subject to
* change without notice.
*
* header "JAVA PROFILE 1.0.1" (0-terminated)
* header "JAVA PROFILE 1.0.1"
or "JAVA PROFILE 1.0.2"
(0-terminated)
* u4 size of identifiers. Identifiers are used to represent
* UTF8 strings, objects, stack traces, etc. They usually
* have the same size as host pointers. For example, on
...
...
@@ -292,11 +292,34 @@ import sun.jvm.hotspot.runtime.*;
* 0x00000002: cpu sampling on/off
* u2 stack trace depth
*
*
* When the header is "JAVA PROFILE 1.0.2" a heap dump can optionally
* be generated as a sequence of heap dump segments. This sequence is
* terminated by an end record. The additional tags allowed by format
* "JAVA PROFILE 1.0.2" are:
*
* HPROF_HEAP_DUMP_SEGMENT denote a heap dump segment
*
* [heap dump sub-records]*
* The same sub-record types allowed by HPROF_HEAP_DUMP
*
* HPROF_HEAP_DUMP_END denotes the end of a heap dump
*
*/
public
class
HeapHprofBinWriter
extends
AbstractHeapGraphWriter
{
// The heap size threshold used to determine if segmented format
// ("JAVA PROFILE 1.0.2") should be used.
private
static
final
long
HPROF_SEGMENTED_HEAP_DUMP_THRESHOLD
=
2L
*
0x40000000
;
// The approximate size of a heap segment. Used to calculate when to create
// a new segment.
private
static
final
long
HPROF_SEGMENTED_HEAP_DUMP_SEGMENT_SIZE
=
1L
*
0x40000000
;
// hprof binary file header
private
static
final
String
HPROF_HEADER
=
"JAVA PROFILE 1.0.1"
;
private
static
final
String
HPROF_HEADER_1_0_1
=
"JAVA PROFILE 1.0.1"
;
private
static
final
String
HPROF_HEADER_1_0_2
=
"JAVA PROFILE 1.0.2"
;
// constants in enum HprofTag
private
static
final
int
HPROF_UTF8
=
0x01
;
...
...
@@ -312,6 +335,10 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
private
static
final
int
HPROF_CPU_SAMPLES
=
0x0D
;
private
static
final
int
HPROF_CONTROL_SETTINGS
=
0x0E
;
// 1.0.2 record types
private
static
final
int
HPROF_HEAP_DUMP_SEGMENT
=
0x1C
;
private
static
final
int
HPROF_HEAP_DUMP_END
=
0x2C
;
// Heap dump constants
// constants in enum HprofGcTag
private
static
final
int
HPROF_GC_ROOT_UNKNOWN
=
0xFF
;
...
...
@@ -352,11 +379,9 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
private
static
final
int
JVM_SIGNATURE_ARRAY
=
'['
;
private
static
final
int
JVM_SIGNATURE_CLASS
=
'L'
;
public
synchronized
void
write
(
String
fileName
)
throws
IOException
{
// open file stream and create buffered data output stream
FileOutputStream
fos
=
new
FileOutputStream
(
fileName
);
FileChannel
chn
=
fos
.
getChannel
();
fos
=
new
FileOutputStream
(
fileName
);
out
=
new
DataOutputStream
(
new
BufferedOutputStream
(
fos
));
VM
vm
=
VM
.
getVM
();
...
...
@@ -385,6 +410,9 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
FLOAT_SIZE
=
objectHeap
.
getFloatSize
();
DOUBLE_SIZE
=
objectHeap
.
getDoubleSize
();
// Check weather we should dump the heap as segments
useSegmentedHeapDump
=
vm
.
getUniverse
().
heap
().
used
()
>
HPROF_SEGMENTED_HEAP_DUMP_THRESHOLD
;
// hprof bin format header
writeFileHeader
();
...
...
@@ -394,38 +422,87 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
// hprof UTF-8 symbols section
writeSymbols
();
// HPROF_LOAD_CLASS records for all classes
writeClasses
();
// write heap data now
out
.
writeByte
((
byte
)
HPROF_HEAP_DUMP
);
out
.
writeInt
(
0
);
// relative timestamp
// remember position of dump length, we will fixup
// length later - hprof format requires length.
out
.
flush
();
long
dumpStart
=
chn
.
position
();
// write dummy length of 0 and we'll fix it later.
out
.
writeInt
(
0
);
// write CLASS_DUMP records
writeClassDumpRecords
();
// this will write heap data into the buffer stream
super
.
write
();
// flush buffer stream.
out
.
flush
();
// Fill in final length
fillInHeapRecordLength
();
if
(
useSegmentedHeapDump
)
{
// Write heap segment-end record
out
.
writeByte
((
byte
)
HPROF_HEAP_DUMP_END
);
out
.
writeInt
(
0
);
out
.
writeInt
(
0
);
}
// flush buffer stream and throw it.
out
.
flush
();
out
=
null
;
// close the file stream
fos
.
close
();
}
@Override
protected
void
writeHeapRecordPrologue
()
throws
IOException
{
if
(
currentSegmentStart
==
0
)
{
// write heap data header, depending on heap size use segmented heap
// format
out
.
writeByte
((
byte
)
(
useSegmentedHeapDump
?
HPROF_HEAP_DUMP_SEGMENT
:
HPROF_HEAP_DUMP
));
out
.
writeInt
(
0
);
// remember position of dump length, we will fixup
// length later - hprof format requires length.
out
.
flush
();
currentSegmentStart
=
fos
.
getChannel
().
position
();
// write dummy length of 0 and we'll fix it later.
out
.
writeInt
(
0
);
}
}
@Override
protected
void
writeHeapRecordEpilogue
()
throws
IOException
{
if
(
useSegmentedHeapDump
)
{
out
.
flush
();
if
((
fos
.
getChannel
().
position
()
-
currentSegmentStart
-
4
)
>=
HPROF_SEGMENTED_HEAP_DUMP_SEGMENT_SIZE
)
{
fillInHeapRecordLength
();
currentSegmentStart
=
0
;
}
}
}
private
void
fillInHeapRecordLength
()
throws
IOException
{
// now get current position to calculate length
long
dumpEnd
=
chn
.
position
();
long
dumpEnd
=
fos
.
getChannel
().
position
();
// calculate length of heap data
int
dumpLen
=
(
int
)
(
dumpEnd
-
dumpStart
-
4
);
long
dumpLenLong
=
(
dumpEnd
-
currentSegmentStart
-
4L
);
// Check length boundary, overflow could happen but is _very_ unlikely
if
(
dumpLenLong
>=
(
4L
*
0x40000000
)){
throw
new
RuntimeException
(
"Heap segment size overflow."
);
}
// Save the current position
long
currentPosition
=
fos
.
getChannel
().
position
();
// seek the position to write length
chn
.
position
(
dumpStart
);
fos
.
getChannel
().
position
(
currentSegmentStart
);
int
dumpLen
=
(
int
)
dumpLenLong
;
// write length as integer
fos
.
write
((
dumpLen
>>>
24
)
&
0xFF
);
...
...
@@ -433,8 +510,8 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
fos
.
write
((
dumpLen
>>>
8
)
&
0xFF
);
fos
.
write
((
dumpLen
>>>
0
)
&
0xFF
);
//
close the file stream
fos
.
close
(
);
//
Reset to previous current position
fos
.
getChannel
().
position
(
currentPosition
);
}
private
void
writeClassDumpRecords
()
throws
IOException
{
...
...
@@ -443,7 +520,9 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
sysDict
.
allClassesDo
(
new
SystemDictionary
.
ClassVisitor
()
{
public
void
visit
(
Klass
k
)
{
try
{
writeHeapRecordPrologue
();
writeClassDumpRecord
(
k
);
writeHeapRecordEpilogue
();
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
e
);
}
...
...
@@ -884,7 +963,12 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
// writes hprof binary file header
private
void
writeFileHeader
()
throws
IOException
{
// version string
out
.
writeBytes
(
HPROF_HEADER
);
if
(
useSegmentedHeapDump
)
{
out
.
writeBytes
(
HPROF_HEADER_1_0_2
);
}
else
{
out
.
writeBytes
(
HPROF_HEADER_1_0_1
);
}
out
.
writeByte
((
byte
)
'\0'
);
// write identifier size. we use pointers as identifiers.
...
...
@@ -976,6 +1060,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
private
static
final
int
EMPTY_FRAME_DEPTH
=
-
1
;
private
DataOutputStream
out
;
private
FileOutputStream
fos
;
private
Debugger
dbg
;
private
ObjectHeap
objectHeap
;
private
SymbolTable
symTbl
;
...
...
@@ -983,6 +1068,10 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
// oopSize of the debuggee
private
int
OBJ_ID_SIZE
;
// Added for hprof file format 1.0.2 support
private
boolean
useSegmentedHeapDump
;
private
long
currentSegmentStart
;
private
long
BOOLEAN_BASE_OFFSET
;
private
long
BYTE_BASE_OFFSET
;
private
long
CHAR_BASE_OFFSET
;
...
...
@@ -1005,6 +1094,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
private
static
class
ClassData
{
int
instSize
;
List
fields
;
ClassData
(
int
instSize
,
List
fields
)
{
this
.
instSize
=
instSize
;
this
.
fields
=
fields
;
...
...
test/TEST.groups
浏览文件 @
40934fb4
...
...
@@ -84,7 +84,9 @@ needs_jdk = \
runtime/NMT/VirtualAllocTestType.java \
runtime/RedefineObject/TestRedefineObject.java \
runtime/XCheckJniJsig/XCheckJSig.java \
serviceability/attach/AttachWithStalePidFile.java
serviceability/attach/AttachWithStalePidFile.java \
serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java
# JRE adds further tests to compact3
#
...
...
test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapProc.java
0 → 100644
浏览文件 @
40934fb4
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
java.lang.management.ManagementFactory
;
import
java.lang.management.RuntimeMXBean
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.util.ArrayList
;
import
java.util.List
;
import
sun.management.VMManagement
;
public
class
JMapHProfLargeHeapProc
{
private
static
final
List
<
byte
[]>
heapGarbage
=
new
ArrayList
<>();
public
static
void
main
(
String
[]
args
)
throws
Exception
{
buildLargeHeap
(
args
);
// Print our pid on stdout
System
.
out
.
println
(
"PID["
+
getProcessId
()
+
"]"
);
// Wait for input before termination
System
.
in
.
read
();
}
private
static
void
buildLargeHeap
(
String
[]
args
)
{
for
(
long
i
=
0
;
i
<
Integer
.
parseInt
(
args
[
0
]);
i
++)
{
heapGarbage
.
add
(
new
byte
[
1024
]);
}
}
public
static
int
getProcessId
()
throws
Exception
{
// Get the current process id using a reflection hack
RuntimeMXBean
runtime
=
ManagementFactory
.
getRuntimeMXBean
();
Field
jvm
=
runtime
.
getClass
().
getDeclaredField
(
"jvm"
);
jvm
.
setAccessible
(
true
);
VMManagement
mgmt
=
(
sun
.
management
.
VMManagement
)
jvm
.
get
(
runtime
);
Method
pid_method
=
mgmt
.
getClass
().
getDeclaredMethod
(
"getProcessId"
);
pid_method
.
setAccessible
(
true
);
int
pid
=
(
Integer
)
pid_method
.
invoke
(
mgmt
);
return
pid
;
}
}
test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java
0 → 100644
浏览文件 @
40934fb4
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
java.io.BufferedReader
;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.FileReader
;
import
java.io.IOException
;
import
java.io.Reader
;
import
java.nio.CharBuffer
;
import
java.util.Arrays
;
import
java.util.Scanner
;
import
com.oracle.java.testlibrary.Asserts
;
import
com.oracle.java.testlibrary.JDKToolFinder
;
import
com.oracle.java.testlibrary.JDKToolLauncher
;
import
com.oracle.java.testlibrary.OutputAnalyzer
;
import
com.oracle.java.testlibrary.Platform
;
import
com.oracle.java.testlibrary.ProcessTools
;
/*
* @test
* @bug 6313383
* @key regression
* @summary Regression test for hprof export issue due to large heaps (>2G)
* @library /testlibrary
* @compile JMapHProfLargeHeapProc.java
* @run main JMapHProfLargeHeapTest
*/
public
class
JMapHProfLargeHeapTest
{
private
static
final
String
HEAP_DUMP_FILE_NAME
=
"heap.hprof"
;
private
static
final
String
HPROF_HEADER_1_0_1
=
"JAVA PROFILE 1.0.1"
;
private
static
final
String
HPROF_HEADER_1_0_2
=
"JAVA PROFILE 1.0.2"
;
private
static
final
long
M
=
1024L
;
private
static
final
long
G
=
1024L
*
M
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
// If we are on MacOSX, test if JMap tool is signed, otherwise return
// since test will fail with privilege error.
if
(
Platform
.
isOSX
())
{
String
jmapToolPath
=
JDKToolFinder
.
getCurrentJDKTool
(
"jmap"
);
ProcessBuilder
codesignProcessBuilder
=
new
ProcessBuilder
(
"codesign"
,
"-v"
,
jmapToolPath
);
Process
codesignProcess
=
codesignProcessBuilder
.
start
();
OutputAnalyzer
analyser
=
new
OutputAnalyzer
(
codesignProcess
);
try
{
analyser
.
shouldNotContain
(
"code object is not signed at all"
);
System
.
out
.
println
(
"Signed jmap found at: "
+
jmapToolPath
);
}
catch
(
Exception
e
)
{
// Abort since we can't know if the test will work
System
.
out
.
println
(
"Test aborted since we are on MacOSX and the jmap tool is not signed."
);
return
;
}
}
// Small heap 22 megabytes, should create 1.0.1 file format
testHProfFileFormat
(
"-Xmx1g"
,
22
*
M
,
HPROF_HEADER_1_0_1
);
/**
* This test was deliberately commented out since the test system lacks
* support to handle the requirements for this kind of heap size in a
* good way. If or when it becomes possible to run this kind of tests in
* the test environment the test should be enabled again.
* */
// Large heap 2,2 gigabytes, should create 1.0.2 file format
// testHProfFileFormat("-Xmx4g", 2 * G + 2 * M, HPROF_HEADER_1_0_2);
}
private
static
void
testHProfFileFormat
(
String
vmArgs
,
long
heapSize
,
String
expectedFormat
)
throws
Exception
,
IOException
,
InterruptedException
,
FileNotFoundException
{
ProcessBuilder
procBuilder
=
ProcessTools
.
createJavaProcessBuilder
(
vmArgs
,
"JMapHProfLargeHeapProc"
,
String
.
valueOf
(
heapSize
));
procBuilder
.
redirectError
(
ProcessBuilder
.
Redirect
.
INHERIT
);
Process
largeHeapProc
=
procBuilder
.
start
();
try
(
Scanner
largeHeapScanner
=
new
Scanner
(
largeHeapProc
.
getInputStream
());)
{
String
pidstring
=
null
;
while
((
pidstring
=
largeHeapScanner
.
findInLine
(
"PID\\[[0-9].*\\]"
))
==
null
)
{
Thread
.
sleep
(
500
);
}
int
pid
=
Integer
.
parseInt
(
pidstring
.
substring
(
4
,
pidstring
.
length
()
-
1
));
System
.
out
.
println
(
"Extracted pid: "
+
pid
);
JDKToolLauncher
jMapLauncher
=
JDKToolLauncher
.
create
(
"jmap"
,
false
);
jMapLauncher
.
addToolArg
(
"-dump:format=b,file="
+
pid
+
"-"
+
HEAP_DUMP_FILE_NAME
);
jMapLauncher
.
addToolArg
(
String
.
valueOf
(
pid
));
ProcessBuilder
jMapProcessBuilder
=
new
ProcessBuilder
(
jMapLauncher
.
getCommand
());
System
.
out
.
println
(
"jmap command: "
+
Arrays
.
toString
(
jMapLauncher
.
getCommand
()));
Process
jMapProcess
=
jMapProcessBuilder
.
start
();
OutputAnalyzer
analyzer
=
new
OutputAnalyzer
(
jMapProcess
);
analyzer
.
shouldHaveExitValue
(
0
);
analyzer
.
shouldContain
(
pid
+
"-"
+
HEAP_DUMP_FILE_NAME
);
analyzer
.
shouldContain
(
"Heap dump file created"
);
largeHeapProc
.
getOutputStream
().
write
(
'\n'
);
File
dumpFile
=
new
File
(
pid
+
"-"
+
HEAP_DUMP_FILE_NAME
);
Asserts
.
assertTrue
(
dumpFile
.
exists
(),
"Heap dump file not found."
);
try
(
Reader
reader
=
new
BufferedReader
(
new
FileReader
(
dumpFile
)))
{
CharBuffer
buf
=
CharBuffer
.
allocate
(
expectedFormat
.
length
());
reader
.
read
(
buf
);
buf
.
clear
();
Asserts
.
assertEQ
(
buf
.
toString
(),
expectedFormat
,
"Wrong file format. Expected '"
+
expectedFormat
+
"', but found '"
+
buf
.
toString
()
+
"'"
);
}
System
.
out
.
println
(
"Success!"
);
}
finally
{
largeHeapProc
.
destroyForcibly
();
}
}
}
test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java
浏览文件 @
40934fb4
...
...
@@ -23,20 +23,17 @@
package
com.oracle.java.testlibrary
;
import
java.util.List
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
com.oracle.java.testlibrary.JDKToolFinder
;
import
com.oracle.java.testlibrary.ProcessTools
;
import
java.util.List
;
/**
* A utility for constructing command lines for starting JDK tool processes.
*
* The JDKToolLauncher can in particular be combined with a
* java.lang.ProcessBuilder to easily run a JDK tool. For example, the
*
following code run {@code jmap -heap} against a process with GC logging
* t
urned on for t
he {@code jmap} process:
* java.lang.ProcessBuilder to easily run a JDK tool. For example, the
following
*
code run {@code jmap -heap} against a process with GC logging turned on for
* the {@code jmap} process:
*
* <pre>
* {@code
...
...
@@ -55,19 +52,39 @@ public class JDKToolLauncher {
private
final
List
<
String
>
vmArgs
=
new
ArrayList
<
String
>();
private
final
List
<
String
>
toolArgs
=
new
ArrayList
<
String
>();
private
JDKToolLauncher
(
String
tool
)
{
executable
=
JDKToolFinder
.
getJDKTool
(
tool
);
private
JDKToolLauncher
(
String
tool
,
boolean
useCompilerJDK
)
{
if
(
useCompilerJDK
)
{
executable
=
JDKToolFinder
.
getJDKTool
(
tool
);
}
else
{
executable
=
JDKToolFinder
.
getCurrentJDKTool
(
tool
);
}
vmArgs
.
addAll
(
Arrays
.
asList
(
ProcessTools
.
getPlatformSpecificVMArgs
()));
}
/**
* Creates a new JDKToolLauncher for the specified tool.
* Creates a new JDKToolLauncher for the specified tool. Using tools path
* from the compiler JDK.
*
* @param tool The name of the tool
* @param tool
* The name of the tool
* @return A new JDKToolLauncher
*/
public
static
JDKToolLauncher
create
(
String
tool
)
{
return
new
JDKToolLauncher
(
tool
);
return
new
JDKToolLauncher
(
tool
,
true
);
}
/**
* Creates a new JDKToolLauncher for the specified tool.
*
* @param tool
* The name of the tool
* @param useCompilerPath
* If true use the compiler JDK path, otherwise use the tested
* JDK path.
* @return A new JDKToolLauncher
*/
public
static
JDKToolLauncher
create
(
String
tool
,
boolean
useCompilerJDK
)
{
return
new
JDKToolLauncher
(
tool
,
useCompilerJDK
);
}
/**
...
...
@@ -80,7 +97,8 @@ public class JDKToolLauncher {
* automatically added.
*
*
* @param arg The argument to VM running the tool
* @param arg
* The argument to VM running the tool
* @return The JDKToolLauncher instance
*/
public
JDKToolLauncher
addVMArg
(
String
arg
)
{
...
...
@@ -91,7 +109,8 @@ public class JDKToolLauncher {
/**
* Adds an argument to the tool.
*
* @param arg The argument to the tool
* @param arg
* The argument to the tool
* @return The JDKToolLauncher instance
*/
public
JDKToolLauncher
addToolArg
(
String
arg
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录