classClassLoaderData : public CHeapObj<mtClass> {
...
static ClassLoaderData * _the_null_class_loader_data;
oop _class_loader; // oop used to uniquely identify a class loader// class loader or a canonical class path
Dependencies _dependencies; // holds dependencies from this class loader// data to others.
Metaspace * _metaspace; // Meta-space where meta-data defined by the// classes in the class loader are allocated.
Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup.bool _unloading; // true if this class loader goes awaybool _keep_alive; // if this CLD is kept alive without a keep_alive_object().bool _is_anonymous; // if this CLD is for an anonymous classvolatileint _claimed; // true if claimed, for example during GC traces.// To avoid applying oop closure more than once.// Has to be an int because we cas it.
Klass* _klasses; // The classes defined by the class loader.
JNIHandleBlock* _handles; // Handles to constant pool arrays// These method IDs are created for the class loader and set to NULL when the// class loader is unloaded. They are rarely freed, only for redefine classes// and if they lose a data race in InstanceKlass.
JNIMethodBlock* _jmethod_ids;
// Metadata to be deallocated when it's safe at class unloading, when// this class loader isn't unloaded itself.
GrowableArray<Metadata*>* _deallocate_list;
// Support for walking class loader data objects
ClassLoaderData* _next; /// Next loader_datas created// ReadOnly and ReadWrite metaspaces (static because only on the null// class loader for now).static Metaspace* _ro_metaspace;
static Metaspace* _rw_metaspace;
...
}
ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) :
_class_loader(h_class_loader()),
_is_anonymous(is_anonymous),
// An anonymous class loader data doesn't have anything to keep// it from being unloaded during parsing of the anonymous class.// The null-class-loader should always be kept alive.
_keep_alive(is_anonymous || h_class_loader.is_null()),
_metaspace(NULL), _unloading(false), _klasses(NULL),
_claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
_next(NULL), _dependencies(dependencies),
_metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) {
// empty
}
UNSAFE_ENTRY(jclass, Unsafe_DefineAnonymousClass(JNIEnv *env, jobject unsafe, jclass host_class, jbyteArray data, jobjectArray cp_patches_jh))
{
instanceKlassHandle anon_klass;
jobject res_jh = NULL;
UnsafeWrapper("Unsafe_DefineAnonymousClass");
ResourceMark rm(THREAD);
HeapWord* temp_alloc = NULL;
anon_klass = Unsafe_DefineAnonymousClass_impl(env, host_class, data,
cp_patches_jh,
&temp_alloc, THREAD);
if (anon_klass() != NULL)
res_jh = JNIHandles::make_local(env, anon_klass->java_mirror());
// try/finally clause:if (temp_alloc != NULL) {
FREE_C_HEAP_ARRAY(HeapWord, temp_alloc, mtInternal);
}
// The anonymous class loader data has been artificially been kept alive to// this point. The mirror and any instances of this class have to keep// it alive afterwards.if (anon_klass() != NULL) {
anon_klass->class_loader_data()->set_keep_alive(false);
}
// let caller initialize it as needed...return (jclass) res_jh;
}
UNSAFE_END
}
Klass* SystemDictionary::parse_stream(Symbol* class_name,
Handle class_loader,
Handle protection_domain,
ClassFileStream* st,
KlassHandle host_klass,
GrowableArray<Handle>* cp_patches,
TRAPS) {
TempNewSymbol parsed_name = NULL;
Ticks class_load_start_time = Ticks::now();
ClassLoaderData* loader_data;
if (host_klass.not_null()) {
// Create a new CLD for anonymous class, that uses the same class loader// as the host_klass
assert(EnableInvokeDynamic, "");
guarantee(host_klass->class_loader() == class_loader(), "should be the same");
guarantee(!DumpSharedSpaces, "must not create anonymous classes when dumping");
loader_data = ClassLoaderData::anonymous_class_loader_data(class_loader(), CHECK_NULL);
loader_data->record_dependency(host_klass(), CHECK_NULL);
} else {
loader_data = ClassLoaderData::class_loader_data(class_loader());
}
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
loader_data,
protection_domain,
host_klass,
cp_patches,
parsed_name,
true,
THREAD);
...
}
ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(oop loader, TRAPS) {
// Add a new class loader data to the graph.return ClassLoaderDataGraph::add(loader, true, CHECK_NULL);
}
ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) {
// We need to allocate all the oops for the ClassLoaderData before allocating the// actual ClassLoaderData object.
ClassLoaderData::Dependencies dependencies(CHECK_NULL);
No_Safepoint_Verifier no_safepoints; // we mustn't GC until we've installed the// ClassLoaderData in the graph since the CLD// contains unhandled oops
ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous, dependencies);
...
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现