bb5278d98a
Reviewed-by: tschatzl, aboldtch, mli
123 lines
6.9 KiB
Plaintext
123 lines
6.9 KiB
Plaintext
Copyright (c) 2014, 2021, 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.
|
|
|
|
Here are tests that were developed for "G1 support for long running applications" feature. In effect,
|
|
here is only one test with a lot of configurations.
|
|
|
|
Feature description:
|
|
G1 used to unload classes only during full collections. Goal of feature is to unload unused classes
|
|
without resorting to full gc.
|
|
|
|
What does test checks:
|
|
- that unreferenced classloader will be collected without full gc. This is checked with WhiteBox.is
|
|
ClassAlive method.
|
|
- that referenced classloader will live. This is checked with WhiteBox.isClassAlive method as well.
|
|
Also it is checked that classloader will be finalized and enqueued to queue of phantom references.
|
|
|
|
In what aspects/circumstances checks performed:
|
|
- classloaders that we expect to be collected can be comlpetely unreferenced, referenced with phant
|
|
om reference and with weak reference. Test can check that presence of phantom/weak reference doesn't
|
|
keep classloader alive.
|
|
Test has flag "-referenceMode" that has valid options:
|
|
"phantom" for phantom reference,
|
|
"weak" for weak reference and
|
|
"none" for not keeping reference at all.
|
|
- to avoid class unloading we can keep reference to classloader itself, class or object.
|
|
This behavior can be adjusted with flag "-keep" that has valid options:
|
|
"classloader",
|
|
"class" and
|
|
"object".
|
|
- according to test plan several ways of classloading are covered.
|
|
This behavior is adjusted with "classloadingMethod" flag that has valid options
|
|
"plain",
|
|
"reflection",
|
|
"jni",
|
|
"hidden_classloader".
|
|
- classloaders that we expect to live can be referenced in several ways.
|
|
This behavior can be adjusted with flag "-keepRefMode" that has valid options:
|
|
"strong_reference" for starighforward keeping strong reference,
|
|
"static_field" for keeping reference in static field of alive class,
|
|
"stack_local" for keeping reference in local variable of running thread,
|
|
"thread_field" for keeping reference in field of running thread's object,
|
|
"thread_itself" if we want object to be a running thread itself,
|
|
"static_field_of_root_class". In this case reference will be kept in static field of class that wa
|
|
s loaded by null classloader.
|
|
"jni_global_ref". In this case global reference will be kept in native library.
|
|
"jni_local_ref", In this case local reference will be kept in JNI call in running thread.
|
|
- Another aspect is that class can be humongous.
|
|
Humongous classes can be enabled with "-humongousClass" command line option. Valid options are
|
|
"true" and "false".
|
|
- Another aspect that is covered with tests is that class methods can be compiled by JIT compiler.
|
|
This behavior can be adjusted with "-compilationLevel" and "-compilationNumber" options. First
|
|
one has self-explaining name, latter sets number of optimization/deoptimozation of each class.
|
|
- Next aspect is class redefinition.
|
|
You can enable classes redefinition with "-redefineClasses" flag. Valid options are "true" and
|
|
"false".
|
|
|
|
Test implementation details:
|
|
Test supposed to be ran with G1 gc and -XX:+ExplicitGCProvokesConcurrent option. In the end of exec
|
|
ution test checks if full gc happened. If this is the case the test throws descriptive exception and
|
|
fails.
|
|
|
|
Test guts design:
|
|
Test in loop performs the following until time is over (timelimit is set up with "-stressTime" opti
|
|
on):
|
|
- loads class that gonna live or gonna be unloaded. Decision depends upon Random.nextBoolean().
|
|
- previous action produces collection of Assertions (what assertion is is explained a little bit lat
|
|
er). Assertions are saved into AssertionContainer.
|
|
- takes from AssertionContainer assertions that are already mature for check and performs checks. "M
|
|
ature" means that required number of System.gc() calls happened since assertion was created.
|
|
|
|
What "Assertion" is:
|
|
Assertion incapsulates check that concrete class will be alive or dead. Hazard is that we can't perf
|
|
orm check just after we removed last reference to classloader. We have to wait some number of concurr
|
|
ent-mark-cycles, i.e. System.gc() calls. For this reason we put each assertion in AssertionContainer
|
|
and get back much later, when it's ready for check.
|
|
Classes of assertions form the following simple hierarchy:
|
|
|
|
gc.g1.unloading.check.Assertion
|
|
|| || ||
|
|
\/ || \/
|
|
gc.g1.unloading.check.FinalizedAssertion || gc.g1.unloading.check.PhantomizedAssertion
|
|
\/
|
|
gc.g1.unloading.check.ClassAssertion
|
|
|
|
FinalizedAssertion checks that unreferenced classloader will be finalized.
|
|
PhantomizedAssertion checks that phantom reference to classloader will be enqueued to ReferenceQueue.
|
|
ClassAssertion checks that class will be dead or alive using WhiteBox.isClassAlive method.
|
|
|
|
Other implemention notes:
|
|
There are some other auxiliary threads, but they are not crucial for understanding the logic.
|
|
There are a lot of configurations of the same test in testlist. All configurations use the same mai
|
|
n method as entry point, but impose different test flags. Configurations are autogenerated with "gene
|
|
rate.sh" script.
|
|
|
|
Other test options:
|
|
-DFailTestIfNothingChecked=true. (vm flag) Set this if you want test to fail if nothing was checked
|
|
and test appeared to be useless. It can happen, for example, in slow modes that force compilation.
|
|
-numberOfChecksLimit. (test flag) Set this number if you want test to pass after certain number of c
|
|
hecks performed. (Not to waste time.) To some extent this turns stress test into functional test.
|
|
-numberOfGCsBeforeCheck. (test flag) This option sets number of System.gc() calls that have to be do
|
|
ne before each assertion will be ready to perform checks.
|
|
-inMemoryCompilation. (test flag) This option defines the way of classes creation. If this is true t
|
|
hen classes are compiled with javac API. If false - classes are produced by rewriting classname in "g
|
|
olden" bytecode.
|