Java 具有字节伙伴的一次性类加载器
在我们的应用程序中,我们为特定的作业使用特定的类加载器(Eclipse环境)。Byte Buddy正在维护这些类加载器,并将它们上的引用存储在类Nexus中。我们正在关闭并删除这些类加载器。但是这些类加载器上的引用仍然保留在Nexus类中。Java 具有字节伙伴的一次性类加载器,java,byte-buddy,Java,Byte Buddy,在我们的应用程序中,我们为特定的作业使用特定的类加载器(Eclipse环境)。Byte Buddy正在维护这些类加载器,并将它们上的引用存储在类Nexus中。我们正在关闭并删除这些类加载器。但是这些类加载器上的引用仍然保留在Nexus类中。 是否有可能说ByteBuddy类加载器是绝对的,因此可以从ByteBuddy维护的类加载器集合中删除 Nexus类充当具有活动初始化策略的类的中间调度器。类写入此nexus的原因如下: 您使用的是带有初始化策略的AgentBuilder。除了对该类型使用活动
是否有可能说ByteBuddy类加载器是绝对的,因此可以从ByteBuddy维护的类加载器集合中删除 Nexus类充当具有活动初始化策略的类的中间调度器。类写入此nexus的原因如下:
初始化策略的AgentBuilder
。除了对该类型使用活动的LoadedTypeInitializer
之外,还使用了自注入
TypeResolutionStrategy.Active
Nexus
在加载类之前收到一个条目,该条目应在加载后立即删除。其概念如下:(1)或(2)时,在加载类之前,Byte Buddy在nexus中注册加载的类型初始值设定项:
LoadedTypeInitializer initializer = instrument("Foo");
Nexus.register("Foo", classLoaderOfFoo, 42);
为了确保类完全初始化(例如设置静态字段),在执行任何代码之前,Byte Buddy会将以下代码添加到类型初始值设定项的开头:
class Foo {
static {
Nexus.initialize(Foo.class, 42);
}
}
通过这种方式,Byte Buddy可以确保Foo
在首次使用之前完全初始化
最有可能的情况是,在处理类装入器之前,不会运行每个插入指令的类的初始值设定项,从而导致引用被卡住。我会想办法解决这个问题
更新:这现在是可能的,并将作为Byte Buddy 1.5.5的一部分发布。类加载器现在只被Nexus
弱引用,并且可以注册一个自定义初始化策略.SelfInjection.Split
(默认值),它将NexusAccessor
作为单个参数。这样的nexus访问器允许注册引用队列来清理此类引用。例如:
ReferenceQueue<ClassLoader> refQueue = new ReferenceQueue<ClassLoader>();
NexusAccessor accessor = new NexusAccessor(refQueue);
new AgentBuilder.Default()
.with(new AgentBuilder.InitializationStrategy.SelfInjection.Split(accessor));
ReferenceQueue refQueue=new ReferenceQueue();
NexusAccessor accessor=新的NexusAccessor(refQueue);
新建AgentBuilder.Default()
.with(new-AgentBuilder.InitializationStrategy.SelfInjection.Split(accessor));
现在,一旦类装入器被垃圾收集,在nexus中注册的任何引用都将排队到
refQueue
。您可以通过NexusAccessor.clean(ref)
从nexus中删除此类引用。您可以在此处跟踪此问题:此问题现在已在master上解决。从现在起,类装入器只被弱引用。然而,为了清理元数据,您仍然需要注册一个自定义的初始化策略
,在这里您可以传递一个NexusAccessor
,它反过来将引用队列作为参数。通过这种方式,你可以在类加载器被自动取消引用的同时清理任何元数据。挑剔:你的意思是过时而不是绝对的。这是从Byte Buddy 1.5.5开始发布的。