Java 具有字节伙伴的一次性类加载器

Java 具有字节伙伴的一次性类加载器,java,byte-buddy,Java,Byte Buddy,在我们的应用程序中,我们为特定的作业使用特定的类加载器(Eclipse环境)。Byte Buddy正在维护这些类加载器,并将它们上的引用存储在类Nexus中。我们正在关闭并删除这些类加载器。但是这些类加载器上的引用仍然保留在Nexus类中。 是否有可能说ByteBuddy类加载器是绝对的,因此可以从ByteBuddy维护的类加载器集合中删除 Nexus类充当具有活动初始化策略的类的中间调度器。类写入此nexus的原因如下: 您使用的是带有初始化策略的AgentBuilder。除了对该类型使用活动

在我们的应用程序中,我们为特定的作业使用特定的类加载器(Eclipse环境)。Byte Buddy正在维护这些类加载器,并将它们上的引用存储在类Nexus中。我们正在关闭并删除这些类加载器。但是这些类加载器上的引用仍然保留在Nexus类中。
是否有可能说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开始发布的。