Path: blob/master/runtime/gc_base/ClassLoaderManager.hpp
5986 views
/*******************************************************************************1* Copyright (c) 1991, 2020 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/212223/**24* @file25* @ingroup GC_Base26*/2728#if !defined(CLASSUNLOADMANAGER_HPP_)29#define CLASSUNLOADMANAGER_HPP_3031#include "j9.h"32#include "j9cfg.h"333435#include "BaseNonVirtual.hpp"36#include "EnvironmentBase.hpp"37#include "GCExtensions.hpp"3839/* forward declarations to avoid cyclic include dependencies */40class MM_GCExtensions;41class MM_GlobalCollector;42class MM_HeapMap;43class MM_ClassUnloadStats;4445class MM_ClassLoaderManager : public MM_BaseNonVirtual46{47friend class GC_ClassLoaderLinkedListIterator;4849public:50protected:51private:52#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)53omrthread_monitor_t _undeadSegmentListMonitor;54J9MemorySegment *_firstUndeadSegment;55UDATA _undeadSegmentsTotalSize;56UDATA _lastUnloadNumOfClassLoaders; /**< number of class loaders last seen during a dynamic class unloading pass */57UDATA _lastUnloadNumOfAnonymousClasses; /**< number of anonymous classes last seen during a dynamic class unloading pass */58#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */59MM_GlobalCollector *_globalCollector; /**< Pointer to the global collector. Used for yielding */60J9ClassLoader *_classLoaders; /**< Linked list of classloaders */61MM_GCExtensions *_extensions; /**< GC extensions structure */62J9JavaVM *_javaVM; /**< Pointer to the Java VM */63omrthread_monitor_t _classLoaderListMonitor; /**< monitor that controls modification of the classLoader linked list */6465public:66static MM_ClassLoaderManager *newInstance(MM_EnvironmentBase *env, MM_GlobalCollector *globalCollector);67void kill(MM_EnvironmentBase *env);6869MM_ClassLoaderManager(MM_EnvironmentBase *env, MM_GlobalCollector *globalCollector) :70MM_BaseNonVirtual()71#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)72,_undeadSegmentListMonitor(NULL)73,_firstUndeadSegment(NULL)74,_undeadSegmentsTotalSize(0)75,_lastUnloadNumOfClassLoaders(0)76,_lastUnloadNumOfAnonymousClasses(0)77#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */78,_globalCollector(globalCollector)79,_classLoaders(NULL)80,_extensions(MM_GCExtensions::getExtensions(env))81,_javaVM((J9JavaVM *)env->getOmrVM()->_language_vm)82,_classLoaderListMonitor(NULL)83{84_typeId = __FUNCTION__;85}8687#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)88/**89* Adds the list of memory segments to the internal queue to be reclaimed later90* @param listRoot The root of the segments to be added (follow nextSegmentInClassLoader link to traverse)91*/92void enqueueUndeadClassSegments(J9MemorySegment *listRoot);9394/**95* Flushes the cached list of segments by calling the VM's freeMemorySegment method96* @param env The environment97*/98void flushUndeadSegments(MM_EnvironmentBase *env);99100/**101* Returns the total amount of memory (in bytes) which would be reclaimed if the buffer were to be flushed102*/103UDATA reclaimableMemory() { return _undeadSegmentsTotalSize; }104105/**106* Returns the number of class loaders last seen during a dynamic class unloading pass107*/108UDATA getLastUnloadNumOfClassLoaders() { return _lastUnloadNumOfClassLoaders; }109110/**111* Set the number of class loaders last seen during a dynamic class unloading pass,112* (i.e. the number of classloaders currently loaded)113*/114void setLastUnloadNumOfClassLoaders();115116/**117* Returns the number of anonymous classes last seen during a dynamic class unloading pass118*/119UDATA getLastUnloadNumOfAnonymousClasses() { return _lastUnloadNumOfAnonymousClasses; }120121/**122* Set the number of anonymous classes last seen during a dynamic class unloading pass,123* (i.e. the number of anonymous classes currently loaded)124*/125void setLastUnloadNumOfAnonymousClasses();126127/**128* Perform initial cleanup for classloader unloading. The current thread has exclusive access.129* The J9AccClassDying bit is set and J9HOOK_VM_CLASS_UNLOAD is triggered for each class that will be unloaded.130* The J9_GC_CLASS_LOADER_DEAD bit is set for each class loader that will be unloaded.131* J9HOOK_VM_CLASSES_UNLOAD is triggered if any classes will be unloaded.132*133* @param env[in] the main GC thread134* @param classLoaderUnloadList[in] the linked list of loaders to unload, connected through the unloadLink field135* @param markMap[in] the markMap to use to test for class loader and classes liveness136* @param classUnloadStats[out] returns the class unloading statistics for classes about to be unloaded137*/138void cleanUpClassLoadersStart(MM_EnvironmentBase *env, J9ClassLoader* classLoaderUnloadList, MM_HeapMap *markMap, MM_ClassUnloadStats *classUnloadStats);139140/**141* Perform final cleanup for classloader unloading. The current thread has exclusive access.142*143* Any classes in the subclass hierarchy which are identified as dying are removed.144*145* RAM segments in the J9ClassLoaders in unloadLink are changed to UNDEAD segments and added146* to reclaimedSegments. ROM segments in the J9ClassLoaders in the unloadLink are freed.147*148* All J9ClassLoaders in unloadLink are freed.149*150* @note Shared libraries associated with dead classloaders are NOT unloaded by this function. Such151* classloaders should not be on the unloadLink list.152*153* @param env[in] the current thread154* @param unloadLink a list of non-finalizable dead classloaders, linked by J9ClassLoader::unloadLink155*156* @return the count of classes unloaded157*/158void cleanUpClassLoadersEnd(MM_EnvironmentBase *env, J9ClassLoader* unloadLink);159160/**161* Frees all the ROMClass segments in the list reachable from segment following nextSegmentInClassLoader and162* sets all RAMClass segments to UNDEADClass segments and prepends them to the reclaimedSegments list, by163* reference, linked via nextSegmentInClassLoader164*/165void cleanUpSegmentsAlongClassLoaderLink(J9JavaVM *javaVM, J9MemorySegment *segment, J9MemorySegment **reclaimedSegments);166167/**168* Remove the specified class from its subclass traversal list.169* The class is moved into a trivial list consisting of itself.170* @param env[in] the current thread171* @param clazzPtr[in] the class to remove172*/173void removeFromSubclassHierarchy(MM_EnvironmentBase *env, J9Class *clazzPtr);174175/**176* Perform generic clean up for a list of class loaders to unload.177* @param env[in] the current thread178* @param classLoader[in] the list of class loaders to clean up179* @param reclaimedSegments[out] a linked list of memory segments to be reclaimed by cleanUpClassLoadersEnd180* @param unloadLink[out] a linked list of class loaders to be reclaimed by cleanUpClassLoadersEnd181* @param finalizationRequired[out] set to true if the finalize thread must be started, unmodified otherwise182*/183void cleanUpClassLoaders(MM_EnvironmentBase *env, J9ClassLoader *classLoadersUnloadedList, J9MemorySegment** reclaimedSegments, J9ClassLoader ** unloadLink, volatile bool* finalizationRequired);184185/**186* Attempt to enter the class unload mutex if it is uncontended.187* @param env[in] the current thread188* @return true on success, false if the JIT has the mutex locked189*/190bool tryEnterClassUnloadMutex(MM_EnvironmentBase *env);191192/**193* Enter the class unload mutex, waiting for the JIT to release it if necessary.194* @param env[in] the current thread195* @return the time, in microseconds, the GC was forced to wait196*/197U_64 enterClassUnloadMutex(MM_EnvironmentBase *env);198199/**200* Release the class unload mutex.201* @param env[in] the current thread202*/203void exitClassUnloadMutex(MM_EnvironmentBase *env);204205/**206* Using a mark map to identify liveness, build a linked list of class loaders to unload.207* @param env[in] the current thread208* @param markMap[in] the markMap to use to test for class loader liveness209* @param classUnloadStats[out] returns the class unloading statistics with class loaders visited210* @return the head of a linked list of class loaders to be unloaded211*/212J9ClassLoader *identifyClassLoadersToUnload(MM_EnvironmentBase *env, MM_HeapMap *markMap, MM_ClassUnloadStats *classUnloadStats);213214/**215* Clean up memory segments in anonymous classloader216* @param env[in] the current thread217* @param reclaimedSegments[out] a linked list of memory segments to be reclaimed by cleanUpClassLoadersEnd218*/219void cleanUpSegmentsInAnonymousClassLoader(MM_EnvironmentBase *env, J9MemorySegment **reclaimedSegments);220221#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */222223/**224* Answer true if class unloading should be attempted, or false if insufficient class loading225* activity has occurred226*/227bool isTimeForClassUnloading(MM_EnvironmentBase *env);228229void unlinkClassLoader(J9ClassLoader *classLoader);230void linkClassLoader(J9ClassLoader *classLoader);231232protected:233bool initialize(MM_EnvironmentBase *env);234void tearDown(MM_EnvironmentBase *env);235private:236237#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)238/**239* Scan classloader for dying classes and add them to the list240* @param env[in] the current thread241* @param classLoader[in] the list of class loaders to clean up242* @param markMap[in] the markMap to use to test for class loader liveness243* @param setAll[in] bool if true if all classes must be set dying, if false unmarked classes only244* @param classUnloadListStart[in] root of list dying classes should be added to245* @param classUnloadCountOut[out] number of classes dying added to the list246* @return new root to list of dying classes247*/248J9Class *addDyingClassesToList(MM_EnvironmentBase *env, J9ClassLoader * classLoader, MM_HeapMap *markMap, bool setAll, J9Class *classUnloadListStart, UDATA *classUnloadCountOut);249250#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */251252};253254#endif /* CLASSUNLOADMANAGER_HPP_ */255256257