Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
0a318eb7
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看板
提交
0a318eb7
编写于
7月 20, 2018
作者:
R
robm
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
20bfd28a
f4e142b5
变更
9
显示空白变更内容
内联
并排
Showing
9 changed file
with
252 addition
and
60 deletion
+252
-60
make/linux/makefiles/defs.make
make/linux/makefiles/defs.make
+32
-22
make/linux/makefiles/jsig.make
make/linux/makefiles/jsig.make
+6
-3
make/linux/makefiles/saproc.make
make/linux/makefiles/saproc.make
+6
-3
make/linux/makefiles/vm.make
make/linux/makefiles/vm.make
+6
-3
src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
+19
-10
src/share/vm/gc_implementation/g1/g1RootProcessor.cpp
src/share/vm/gc_implementation/g1/g1RootProcessor.cpp
+38
-13
src/share/vm/gc_implementation/g1/g1RootProcessor.hpp
src/share/vm/gc_implementation/g1/g1RootProcessor.hpp
+22
-1
src/share/vm/runtime/arguments.cpp
src/share/vm/runtime/arguments.cpp
+7
-5
test/gc/class_unloading/TestClassUnloadingDisabled.java
test/gc/class_unloading/TestClassUnloadingDisabled.java
+116
-0
未找到文件。
make/linux/makefiles/defs.make
浏览文件 @
0a318eb7
...
...
@@ -239,11 +239,13 @@ EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
# client and server subdirectories have symbolic links to ../libjsig.so
EXPORT_LIST
+=
$(EXPORT_JRE_LIB_ARCH_DIR)
/libjsig.
$(LIBRARY_SUFFIX)
ifeq
($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifneq
($(STRIP_POLICY),no_strip)
ifeq
($(ZIP_DEBUGINFO_FILES),1)
EXPORT_LIST
+=
$(EXPORT_JRE_LIB_ARCH_DIR)
/libjsig.diz
else
EXPORT_LIST
+=
$(EXPORT_JRE_LIB_ARCH_DIR)
/libjsig.debuginfo
endif
endif
endif
EXPORT_SERVER_DIR
=
$(EXPORT_JRE_LIB_ARCH_DIR)
/server
EXPORT_CLIENT_DIR
=
$(EXPORT_JRE_LIB_ARCH_DIR)
/client
...
...
@@ -253,24 +255,28 @@ ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT
EXPORT_LIST
+=
$(EXPORT_SERVER_DIR)
/Xusage.txt
EXPORT_LIST
+=
$(EXPORT_SERVER_DIR)
/libjvm.
$(LIBRARY_SUFFIX)
ifeq
($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifneq
($(STRIP_POLICY),no_strip)
ifeq
($(ZIP_DEBUGINFO_FILES),1)
EXPORT_LIST
+=
$(EXPORT_SERVER_DIR)
/libjvm.diz
else
EXPORT_LIST
+=
$(EXPORT_SERVER_DIR)
/libjvm.debuginfo
endif
endif
endif
endif
ifeq
($(JVM_VARIANT_CLIENT),true)
EXPORT_LIST
+=
$(EXPORT_CLIENT_DIR)
/Xusage.txt
EXPORT_LIST
+=
$(EXPORT_CLIENT_DIR)
/libjvm.
$(LIBRARY_SUFFIX)
ifeq
($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifneq
($(STRIP_POLICY),no_strip)
ifeq
($(ZIP_DEBUGINFO_FILES),1)
EXPORT_LIST
+=
$(EXPORT_CLIENT_DIR)
/libjvm.diz
else
EXPORT_LIST
+=
$(EXPORT_CLIENT_DIR)
/libjvm.debuginfo
endif
endif
endif
endif
ifeq
($(JVM_VARIANT_MINIMAL1),true)
...
...
@@ -278,12 +284,14 @@ ifeq ($(JVM_VARIANT_MINIMAL1),true)
EXPORT_LIST
+=
$(EXPORT_MINIMAL_DIR)
/libjvm.
$(LIBRARY_SUFFIX)
ifeq
($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifneq
($(STRIP_POLICY),no_strip)
ifeq
($(ZIP_DEBUGINFO_FILES),1)
EXPORT_LIST
+=
$(EXPORT_MINIMAL_DIR)
/libjvm.diz
else
EXPORT_LIST
+=
$(EXPORT_MINIMAL_DIR)
/libjvm.debuginfo
endif
endif
endif
endif
# Serviceability Binaries
...
...
@@ -293,6 +301,7 @@ ADD_SA_BINARIES/x86 = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
ADD_SA_BINARIES/
sparc
=
$(EXPORT_JRE_LIB_ARCH_DIR)
/libsaproc.
$(LIBRARY_SUFFIX)
\
$(EXPORT_LIB_DIR)
/sa-jdi.jar
ifeq
($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifneq
($(STRIP_POLICY),no_strip)
ifeq
($(ZIP_DEBUGINFO_FILES),1)
ADD_SA_BINARIES/
x86
+=
$(EXPORT_JRE_LIB_ARCH_DIR)
/libsaproc.diz
ADD_SA_BINARIES/
sparc
+=
$(EXPORT_JRE_LIB_ARCH_DIR)
/libsaproc.diz
...
...
@@ -300,6 +309,7 @@ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ADD_SA_BINARIES/
x86
+=
$(EXPORT_JRE_LIB_ARCH_DIR)
/libsaproc.debuginfo
ADD_SA_BINARIES/
sparc
+=
$(EXPORT_JRE_LIB_ARCH_DIR)
/libsaproc.debuginfo
endif
endif
endif
ADD_SA_BINARIES/
ppc
=
ADD_SA_BINARIES/
ia64
=
...
...
make/linux/makefiles/jsig.make
浏览文件 @
0a318eb7
...
...
@@ -56,21 +56,24 @@ $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
$(QUIETLY)
$(CC)
$(SYMFLAG)
$(ARCHFLAG)
$(SHARED_FLAG)
$(PICFLAG)
\
$(LFLAGS_JSIG)
$(JSIG_DEBUG_CFLAGS)
$(EXTRA_CFLAGS)
-o
$@
$<
-ldl
ifeq
($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifneq
($(STRIP_POLICY),no_strip)
$(QUIETLY)
$(OBJCOPY)
--only-keep-debug
$@
$(LIBJSIG_DEBUGINFO)
ifeq
($(STRIP_POLICY),all_strip)
$(QUIETLY)
$(OBJCOPY)
--add-gnu-debuglink
=
$(LIBJSIG_DEBUGINFO)
$@
endif
ifeq
($(STRIP_POLICY),all_strip)
$(QUIETLY)
$(STRIP)
$@
else
ifeq
($(STRIP_POLICY),min_strip)
$(QUIETLY)
$(OBJCOPY)
--add-gnu-debuglink
=
$(LIBJSIG_DEBUGINFO)
$@
$(QUIETLY)
$(STRIP)
-g
$@
endif
# implied else here is no stripping at all
endif
ifneq
($(STRIP_POLICY),no_strip)
ifeq
($(ZIP_DEBUGINFO_FILES),1)
$(ZIPEXE)
-q
-y
$(LIBJSIG_DIZ)
$(LIBJSIG_DEBUGINFO)
$(RM)
$(LIBJSIG_DEBUGINFO)
endif
endif
endif
install_jsig
:
$(LIBJSIG)
...
...
make/linux/makefiles/saproc.make
浏览文件 @
0a318eb7
...
...
@@ -99,21 +99,24 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
-o
$@
\
-lthread_db
ifeq
($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifneq
($(STRIP_POLICY),no_strip)
$(QUIETLY)
$(OBJCOPY)
--only-keep-debug
$@
$(LIBSAPROC_DEBUGINFO)
ifeq
($(STRIP_POLICY),all_strip)
$(QUIETLY)
$(OBJCOPY)
--add-gnu-debuglink
=
$(LIBSAPROC_DEBUGINFO)
$@
endif
ifeq
($(STRIP_POLICY),all_strip)
$(QUIETLY)
$(STRIP)
$@
else
ifeq
($(STRIP_POLICY),min_strip)
$(QUIETLY)
$(OBJCOPY)
--add-gnu-debuglink
=
$(LIBSAPROC_DEBUGINFO)
$@
$(QUIETLY)
$(STRIP)
-g
$@
endif
# implied else here is no stripping at all
endif
ifneq
($(STRIP_POLICY),no_strip)
ifeq
($(ZIP_DEBUGINFO_FILES),1)
$(ZIPEXE)
-q
-y
$(LIBSAPROC_DIZ)
$(LIBSAPROC_DEBUGINFO)
$(RM)
$(LIBSAPROC_DEBUGINFO)
endif
endif
endif
install_saproc
:
$(BUILDLIBSAPROC)
...
...
make/linux/makefiles/vm.make
浏览文件 @
0a318eb7
...
...
@@ -357,21 +357,24 @@ $(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT)
}
ifeq
($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifneq
($(STRIP_POLICY),no_strip)
$(QUIETLY)
$(OBJCOPY)
--only-keep-debug
$@
$(LIBJVM_DEBUGINFO)
ifeq
($(STRIP_POLICY),all_strip)
$(QUIETLY)
$(OBJCOPY)
--add-gnu-debuglink
=
$(LIBJVM_DEBUGINFO)
$@
endif
ifeq
($(STRIP_POLICY),all_strip)
$(QUIETLY)
$(STRIP)
$@
else
ifeq
($(STRIP_POLICY),min_strip)
$(QUIETLY)
$(OBJCOPY)
--add-gnu-debuglink
=
$(LIBJVM_DEBUGINFO)
$@
$(QUIETLY)
$(STRIP)
-g
$@
endif
# implied else here is no stripping at all
endif
ifneq
($(STRIP_POLICY),no_strip)
ifeq
($(ZIP_DEBUGINFO_FILES),1)
$(ZIPEXE)
-q
-y
$(LIBJVM_DIZ)
$(LIBJVM_DEBUGINFO)
$(RM)
$(LIBJVM_DEBUGINFO)
endif
endif
endif
DEST_SUBDIR
=
$(JDK_LIBDIR)
/
$(VM_SUBDIR)
...
...
src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
浏览文件 @
0a318eb7
/*
* Copyright (c) 2001, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 201
8
, 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
...
...
@@ -135,9 +135,16 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
MarkingCodeBlobClosure
follow_code_closure
(
&
GenMarkSweep
::
follow_root_closure
,
!
CodeBlobToOopClosure
::
FixRelocations
);
{
G1RootProcessor
root_processor
(
g1h
);
if
(
ClassUnloading
)
{
root_processor
.
process_strong_roots
(
&
GenMarkSweep
::
follow_root_closure
,
&
GenMarkSweep
::
follow_cld_closure
,
&
follow_code_closure
);
}
else
{
root_processor
.
process_all_roots_no_string_table
(
&
GenMarkSweep
::
follow_root_closure
,
&
GenMarkSweep
::
follow_cld_closure
,
&
follow_code_closure
);
}
}
// Process reference objects found during marking
...
...
@@ -158,6 +165,8 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
// This is the point where the entire marking should have completed.
assert
(
GenMarkSweep
::
_marking_stack
.
is_empty
(),
"Marking should have completed"
);
if
(
ClassUnloading
)
{
// Unload classes and purge the SystemDictionary.
bool
purged_class
=
SystemDictionary
::
do_unloading
(
&
GenMarkSweep
::
is_alive
);
...
...
@@ -166,7 +175,7 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
// Prune dead klasses from subklass/sibling/implementor lists.
Klass
::
clean_weak_klass_links
(
&
GenMarkSweep
::
is_alive
);
}
// Delete entries for dead interned string and clean up unreferenced symbols in symbol table.
G1CollectedHeap
::
heap
()
->
unlink_string_and_symbol_table
(
&
GenMarkSweep
::
is_alive
);
...
...
src/share/vm/gc_implementation/g1/g1RootProcessor.cpp
浏览文件 @
0a318eb7
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015,
2018,
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
...
...
@@ -156,7 +156,7 @@ void G1RootProcessor::evacuate_roots(OopClosure* scan_non_heap_roots,
}
process_vm_roots
(
strong_roots
,
weak_roots
,
phase_times
,
worker_i
);
process_string_table_roots
(
weak_roots
,
phase_times
,
worker_i
);
{
// Now the CM ref_processor roots.
G1GCParPhaseTimesTracker
x
(
phase_times
,
G1GCPhaseTimes
::
CMRefRoots
,
worker_i
);
...
...
@@ -223,18 +223,34 @@ void G1RootProcessor::process_strong_roots(OopClosure* oops,
void
G1RootProcessor
::
process_all_roots
(
OopClosure
*
oops
,
CLDClosure
*
clds
,
CodeBlobClosure
*
blobs
)
{
CodeBlobClosure
*
blobs
,
bool
process_string_table
)
{
process_java_roots
(
oops
,
NULL
,
clds
,
clds
,
NULL
,
NULL
,
0
);
process_vm_roots
(
oops
,
oops
,
NULL
,
0
);
if
(
!
_process_strong_tasks
.
is_task_claimed
(
G1RP_PS_CodeCache_oops_do
)
)
{
CodeCache
::
blobs_do
(
blobs
);
if
(
process_string_table
)
{
process_string_table_roots
(
oops
,
NULL
,
0
);
}
process_code_cache_roots
(
blobs
,
NULL
,
0
);
_process_strong_tasks
.
all_tasks_completed
();
}
void
G1RootProcessor
::
process_all_roots
(
OopClosure
*
oops
,
CLDClosure
*
clds
,
CodeBlobClosure
*
blobs
)
{
process_all_roots
(
oops
,
clds
,
blobs
,
true
);
}
void
G1RootProcessor
::
process_all_roots_no_string_table
(
OopClosure
*
oops
,
CLDClosure
*
clds
,
CodeBlobClosure
*
blobs
)
{
assert
(
!
ClassUnloading
,
"Should only be used when class unloading is disabled"
);
process_all_roots
(
oops
,
clds
,
blobs
,
false
);
}
void
G1RootProcessor
::
process_java_roots
(
OopClosure
*
strong_roots
,
CLDClosure
*
thread_stack_clds
,
CLDClosure
*
strong_clds
,
...
...
@@ -311,14 +327,23 @@ void G1RootProcessor::process_vm_roots(OopClosure* strong_roots,
SystemDictionary
::
roots_oops_do
(
strong_roots
,
weak_roots
);
}
}
}
void
G1RootProcessor
::
process_string_table_roots
(
OopClosure
*
weak_roots
,
G1GCPhaseTimes
*
phase_times
,
uint
worker_i
)
{
assert
(
weak_roots
!=
NULL
,
"Should only be called when all roots are processed"
);
{
G1GCParPhaseTimesTracker
x
(
phase_times
,
G1GCPhaseTimes
::
StringTableRoots
,
worker_i
);
// All threads execute the following. A specific chunk of buckets
// from the StringTable are the individual tasks.
if
(
weak_roots
!=
NULL
)
{
StringTable
::
possibly_parallel_oops_do
(
weak_roots
);
}
}
void
G1RootProcessor
::
process_code_cache_roots
(
CodeBlobClosure
*
code_closure
,
G1GCPhaseTimes
*
phase_times
,
uint
worker_i
)
{
if
(
!
_process_strong_tasks
.
is_task_claimed
(
G1RP_PS_CodeCache_oops_do
))
{
CodeCache
::
blobs_do
(
code_closure
);
}
}
...
...
src/share/vm/gc_implementation/g1/g1RootProcessor.hpp
浏览文件 @
0a318eb7
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015,
2018,
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
...
...
@@ -34,6 +34,7 @@ class CodeBlobClosure;
class
G1CollectedHeap
;
class
G1GCPhaseTimes
;
class
G1ParPushHeapRSClosure
;
class
G1RootClosures
;
class
Monitor
;
class
OopClosure
;
class
SubTasksDone
;
...
...
@@ -71,6 +72,11 @@ class G1RootProcessor : public StackObj {
void
worker_has_discovered_all_strong_classes
();
void
wait_until_all_strong_classes_discovered
();
void
process_all_roots
(
OopClosure
*
oops
,
CLDClosure
*
clds
,
CodeBlobClosure
*
blobs
,
bool
process_string_table
);
void
process_java_roots
(
OopClosure
*
scan_non_heap_roots
,
CLDClosure
*
thread_stack_clds
,
CLDClosure
*
scan_strong_clds
,
...
...
@@ -84,6 +90,14 @@ class G1RootProcessor : public StackObj {
G1GCPhaseTimes
*
phase_times
,
uint
worker_i
);
void
process_string_table_roots
(
OopClosure
*
scan_non_heap_weak_roots
,
G1GCPhaseTimes
*
phase_times
,
uint
worker_i
);
void
process_code_cache_roots
(
CodeBlobClosure
*
code_closure
,
G1GCPhaseTimes
*
phase_times
,
uint
worker_i
);
public:
G1RootProcessor
(
G1CollectedHeap
*
g1h
);
...
...
@@ -114,6 +128,13 @@ public:
OopClosure
*
scan_non_heap_weak_roots
,
uint
worker_i
);
// Apply oops, clds and blobs to strongly and weakly reachable roots in the system,
// the only thing different from process_all_roots is that we skip the string table
// to avoid keeping every string live when doing class unloading.
void
process_all_roots_no_string_table
(
OopClosure
*
oops
,
CLDClosure
*
clds
,
CodeBlobClosure
*
blobs
);
// Inform the root processor about the number of worker threads
void
set_num_workers
(
int
active_workers
);
};
...
...
src/share/vm/runtime/arguments.cpp
浏览文件 @
0a318eb7
...
...
@@ -1377,11 +1377,6 @@ void Arguments::set_cms_and_parnew_gc_flags() {
CFLS_LAB
::
modify_initialization
(
OldPLABSize
,
OldPLABWeight
);
}
if
(
!
ClassUnloading
)
{
FLAG_SET_CMDLINE
(
bool
,
CMSClassUnloadingEnabled
,
false
);
FLAG_SET_CMDLINE
(
bool
,
ExplicitGCInvokesConcurrentAndUnloadsClasses
,
false
);
}
if
(
PrintGCDetails
&&
Verbose
)
{
tty
->
print_cr
(
"MarkStackSize: %uk MarkStackSizeMax: %uk"
,
(
unsigned
int
)
(
MarkStackSize
/
K
),
(
uint
)
(
MarkStackSizeMax
/
K
));
...
...
@@ -1748,6 +1743,13 @@ void Arguments::set_gc_specific_flags() {
// Keeping the heap 100% free is hard ;-) so limit it to 99%.
FLAG_SET_ERGO
(
uintx
,
MinHeapFreeRatio
,
99
);
}
// If class unloading is disabled, also disable concurrent class unloading.
if
(
!
ClassUnloading
)
{
FLAG_SET_CMDLINE
(
bool
,
CMSClassUnloadingEnabled
,
false
);
FLAG_SET_CMDLINE
(
bool
,
ClassUnloadingWithConcurrentMark
,
false
);
FLAG_SET_CMDLINE
(
bool
,
ExplicitGCInvokesConcurrentAndUnloadsClasses
,
false
);
}
#else // INCLUDE_ALL_GCS
assert
(
verify_serial_gc_flags
(),
"SerialGC unset"
);
#endif // INCLUDE_ALL_GCS
...
...
test/gc/class_unloading/TestClassUnloadingDisabled.java
0 → 100644
浏览文件 @
0a318eb7
/*
* Copyright (c) 2018, 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.
*/
/*
* @test
* @key gc
* @bug 8114823
* @requires vm.gc == null
* @requires vm.opt.ExplicitGCInvokesConcurrent != true
* @requires vm.opt.ClassUnloading != true
* @library /testlibrary /testlibrary/whitebox
* @build sun.hotspot.WhiteBox
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
*
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:-ClassUnloading -XX:+UseG1GC TestClassUnloadingDisabled
*
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:-ClassUnloading -XX:+UseSerialGC TestClassUnloadingDisabled
*
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:-ClassUnloading -XX:+UseParallelGC TestClassUnloadingDisabled
*
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:-ClassUnloading -XX:+UseConcMarkSweepGC TestClassUnloadingDisabled
*/
import
java.io.File
;
import
java.io.IOException
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
sun.hotspot.WhiteBox
;
import
com.oracle.java.testlibrary.Asserts
;
public
class
TestClassUnloadingDisabled
{
public
static
void
main
(
String
args
[])
throws
Exception
{
final
WhiteBox
wb
=
WhiteBox
.
getWhiteBox
();
// Fetch the dir where the test class and the class
// to be loaded resides.
String
classDir
=
TestClassUnloadingDisabled
.
class
.
getProtectionDomain
().
getCodeSource
().
getLocation
().
getPath
();
String
className
=
"ClassToLoadUnload"
;
Asserts
.
assertFalse
(
wb
.
isClassAlive
(
className
),
"Should not be loaded yet"
);
// The NoPDClassLoader handles loading classes in the test directory
// and loads them without a protection domain, which in some cases
// keeps the class live regardless of marking state.
NoPDClassLoader
nopd
=
new
NoPDClassLoader
(
classDir
);
nopd
.
loadClass
(
className
);
Asserts
.
assertTrue
(
wb
.
isClassAlive
(
className
),
"Class should be loaded"
);
// Clear the class-loader, class and object references to make
// class unloading possible.
nopd
=
null
;
System
.
gc
();
Asserts
.
assertTrue
(
wb
.
isClassAlive
(
className
),
"Class should not have ben unloaded"
);
}
}
class
NoPDClassLoader
extends
ClassLoader
{
String
path
;
NoPDClassLoader
(
String
path
)
{
this
.
path
=
path
;
}
public
Class
<?>
loadClass
(
String
name
)
throws
ClassNotFoundException
{
byte
[]
cls
=
null
;
File
f
=
new
File
(
path
,
name
+
".class"
);
// Delegate class loading if class not present in the given
// directory.
if
(!
f
.
exists
())
{
return
super
.
loadClass
(
name
);
}
try
{
Path
path
=
Paths
.
get
(
f
.
getAbsolutePath
());
cls
=
Files
.
readAllBytes
(
path
);
}
catch
(
IOException
e
)
{
throw
new
ClassNotFoundException
(
name
);
}
// Define class with no protection domain and resolve it.
return
defineClass
(
name
,
cls
,
0
,
cls
.
length
,
null
);
}
}
class
ClassToLoadUnload
{
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录