当前位置: 首页 > 知识库问答 >
问题:

可用于单元测试的Netty 4/5确定性缓冲区泄漏检测

狄飞鹏
2023-03-14

我在Netty4中读了很多关于缓冲区泄漏检测的文章,对我来说,在单元测试中似乎没有确定的方法来检测此类泄漏。

然而,这种特性对于单元测试的重要性是如此之大,以至于它感觉非常错误,以至于没有关于如何进行测试的明确指导方针。

此外,大多数来源,包括非常原始的文档http://netty.io/wiki/reference-counted-objects.html,通过给出模糊的提示,使事情变得令人惊讶地困惑,比如:

这听起来好像有一种方法可以在单元测试中确定地检测缓冲区分配器中的泄漏,而实际上并没有这种东西,正如Trustin Lee自己在他的回答中所指出的(链接如下)。

难怪这篇文章被各种各样的消息来源转发了几十次,这些消息来源对此一无所知,只是未经测试就复制粘贴文字。

*)Trustin Lee在下面的主题中建议在繁忙的工作负载下运行一个应用程序30秒。Netty 4/5实际上不会检测到Bytebuf的资源泄漏?但对我来说,这不会触发ResourceLeakDetector的检测或任何输出。

*)我还尝试了在下面的主题如何在Java中强制垃圾收集中建议的GC技巧?但这也没有什么不同。

GC是如此不可预测,以至于很难想象如何利用ResourceLeakDetector创建干净彻底的缓冲区泄漏单元测试。

*)另一种方法是对测试运行时创建的每一个ByteBuf测试refCnt。但有时不可能获得每一个这样的引用,因为接口可能声明String作为输入参数,然后它的实现将在内部创建并释放一个ByteBuf实例,单元测试将无法访问该引用,然而,如果没有释放,它将产生泄漏,在单元测试中没有机会检测到。

*)我也找不到一个简单的方法来从分配器中获取所有现有缓冲区的列表,否则可能只需要检查refCnt就可以了。

我想知道是否有人能分享以确定性方式工作的最佳实践,并能在单元测试中实际使用,以一致地发现使用Netty缓冲区分配器的大型代码库中的缓冲区泄漏。

到目前为止,在我看来,单元测试对于这个目的似乎是无用的,除非您在单元测试中长时间运行一个完整的服务器(顺便说一句,这并不能保证您做任何事情,只是在理论上增加了您的机会)。就我所见,对测试的这种限制没有很好的理由存在,但我们有我们所拥有的。

在互联网上有如此多关于这个主题的令人困惑的信息,可悲的是,源于Netty文档本身,以至于我真的希望以一种直截了当的方式陈述事实。

即使我的问题的答案是“这是不可能的”,只要有这篇文章就可以节省一些人大量的研究时间。

附言。一个非常简单的例子来演示缺少输出。如果有人能说出需要做哪些更改才能让这段代码产生泄漏输出,我将非常感激。

http://gist.github.com/codekrolik/e55b8ece07270f40aad85f691696fe6a

共有1个答案

诸正谊
2023-03-14

所以我设法让单元测试为我工作。

其机制如下所示:

1)按照https://github.com/netty/netty/issues/5275中的建议,创建一个禁用缓存的PooledBufferAllocator

PooledByteBufAllocator alloc = new PooledByteBufAllocator(true, 1, 1, 8192, 11, 0, 0, 0);
Bootstrap clientBootstrap = new Bootstrap();
clientBootstrap.option(ChannelOption.ALLOCATOR, alloc);
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.option(ChannelOption.ALLOCATOR, alloc)
    .childOption(ChannelOption.ALLOCATOR, alloc);
assertEquals(0, getActiveDirectBuffers(alloc));
assertEquals(0, getActiveHeapBuffers(alloc));

int getActiveDirectBuffers(PooledByteBufAllocator alloc) {
    int directActive = 0, directAlloc = 0, directDealloc = 0;
    for (PoolArenaMetric arena : alloc.directArenas()) {
        directActive += arena.numActiveAllocations();
        directAlloc += arena.numAllocations();
        directDealloc += arena.numDeallocations();
    }
    System.out.println("directActive " + directActive + " directAlloc " + directAlloc + " directDealloc " + directDealloc);
    return directActive;
}

int getActiveHeapBuffers(PooledByteBufAllocator alloc) {
    int heapActive = 0, heapAlloc = 0, heapDealloc = 0;
    for (PoolArenaMetric arena : alloc.heapArenas()) {
        heapActive += arena.numActiveAllocations();
        heapAlloc += arena.numAllocations();
        heapDealloc += arena.numDeallocations();
    }
    System.out.println("heapActive " + heapActive + " heapAlloc " + heapAlloc + " heapDealloc " + heapDealloc);
    return heapActive;
}
 类似资料:
  • 问题内容: 您可能已经知道,我们中许多拥有大量书面单元测试的人都遇到了这个不容易解决的问题。根据AngularJs 单元测试指南,我使用Jasmine语法编写了大约3500多个单元测试。测试是使用KarmaRunner执行的。 问题是由于内存泄漏,它们无法一次全部执行。在运行它们时,无论在哪个浏览器上运行它们,内存都会累积,并且有时浏览器崩溃并断开连接。我现在知道的最好的解决方法是,在社区中使用的

  • JMeter可以在java应用程序中检测线程泄漏吗?也就是说,可以通过JVisualvm观察线程泄漏,但是JMeter没有任何插件等可以检测Java应用程序中的线程泄漏。如果没有,那么有没有其他性能测试工具可以检测java应用程序中的线程泄漏,为什么Jeter不能这样做?

  • 问题内容: 我收到以下警告: 我在server.js中编写了这样的代码: 如何解决呢? 问题答案: 这是在解释节点eventEmitter文档 这是哪个版本的Node?您还有什么其他代码?那不是正常行为。 简而言之,其:

  • 我试图理解不对任何流调用close()会如何影响系统的性能和功能。为了做到这一点,我创建了下面的测试类。

  • 问题内容: 是否有一些工具可以检测Node.js中的内存泄漏?并告诉我您在测试nodejs应用程序方面的经验。 问题答案: 以下工具对于发现内存泄漏很有用: 节点检查器 还有一个教程可以帮助您在此处查找内存泄漏: https://github.com/felixge/node-memory-leak- tutorial

  • 是否可以在2.3.9版本中启用泄漏检测?正如我之前在这个问题中所说,HiberNate使用的是HikariCP的2.3.3版本。截至2016年2月,他们已经升级了HikariCP的版本,但不幸的是升级到了2.3.9版本 我需要启用泄漏检测才能修复它们。我已将以下行添加到Hibernate配置文件中: 前两行运行正常,可以在调试日志中看到,但是当我添加第三行时,我无法运行应用程序。我也尝试过用代码添