在创建大量ByteBuddy类时,我需要获取任何类型的锁吗



我正在创建几个ByteBuddy类(使用DynamicTypeBuilder(并加载它们。这些类的创建和加载在一个相对简单的线程(主线程;我自己不生成任何线程,也不向ExecutorService提交任何内容(上进行。

我注意到,在单元测试中连续运行几次会产生不同的结果。有时类的创建和加载都很好。其他时候,当生成的字节码随后被使用时,我会从中得到错误(如果重要的话,通常是在我使用withArgumentArrayElements的一般区域;ArrayIndexOutOfBoundsErrors等等;其他时候,这一切都很好(使用相同的输入((。

这感觉像是一种比赛状态,但正如我所说,我不会产生任何线索。由于I没有使用线程,只有ByteBuddy(或JDK(可以使用。我不确定它会在哪里。在创建和加载带有DynamicTypeBuilder.make()getLoaded()的类时,我应该使用ByteBuddy同步机制吗?也许某种类解析正在make()时的后台线程上发生(或者没有发生!(,而我不小心以某种方式阻止了它的完成?也许如果我要立即使用这些类(我是(,我需要提供一个不同的TypeResolutionStrategy?我很困惑,这一点应该很清楚,我不明白为什么一个具有相同输入的单线程程序会产生不同运行方式的生成类。

我加载这些类的模式是:

  1. 尝试使用Class#forName(name, true, Thread.currentThread().getContextClassLoader())加载(通常不存在(类
  2. 如果(当(失败,创建ByteBuddy生成的类,并使用常用的ByteBuddy配方加载它
  3. 如果失败,那只是因为其他线程可能已经创建了该类。在这个单元测试中,没有其他线程。在任何情况下,如果这里发生故障,我重复步骤1,然后在加载失败时抛出异常

除了这些之外,我还应该采取哪些特定于ByteBuddy的措施吗?

Phew!我想我可以把这归因于我代码中的一个错误(谢天谢地(。简单地说,看起来像并发问题的是(很可能(意外共享类名和HashMap迭代顺序的问题:当一个特定的子类被创建并加载时,另一个子类只会被加载(而不是创建(,反之亦然。净效应是看起来像种族状况的效应。

Byte Buddy是完全线程安全的。但它确实尝试在每次调用load时创建一个类,这是一个相当昂贵的操作。为了避免这种情况,Byte Buddy提供了TypeCache机制,允许您实现高效的缓存。

请注意,像cglib这样的库提供自动缓存。Byte Buddy不这样做,因为缓存使用所有输入作为键,并静态引用它们,这很容易造成内存泄漏。此外,密钥效率相当低,这就是Byte Buddy选择这种方法的原因。

相关内容

  • 没有找到相关文章

最新更新