带有byte-buddy的一次性类加载器

时间:2016-11-09 06:49:23

标签: java byte-buddy

在我们的应用程序中,我们使用某些类加载器来完成特定的工作(Eclipse环境)。 Byte Buddy正在维护这些类加载器,并在Nexus类中存储它们的引用。我们正在关闭并删除这些类加载器。但是这些类加载器的引用仍然在Nexus类中。 是否有可能说ByteBuddy类加载器是绝对的,因此可以从ByteBuddy维护的类加载器集合中删除?

1 个答案:

答案 0 :(得分:1)

Nexus类充当具有活动初始化策略的类的中间调度程序。类被写入这个关系,因为:

  1. 除了为此类型使用有效AgentBuilder外,您使用InitilaizationStrategy.SelfInjecting LoadedTypeInitializer
  2. 您在定义新类型时使用TypeResolutionStrategy.Active
  3. 在这两种情况下,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弱引用,并且可以注册自定义InitializationStrategy.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));
    

    现在,一旦类加载器被垃圾收集,在nexus中注册的任何引用都将排队到refQueue。您可以通过NexusAccessor.clean(ref)