| Copyright (c) 2014, 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. |
| |
| 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", |
| "anonymous_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. |
| |
| 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. |
| |
| |