gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:53:47 25 4
gpt4 key购买 nike

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

但是,这种功能对于单元测试的重要性如此之大,以至于没有关于如何进行的明确指南,这让人感觉很不对。

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

“以下输出显示了我们的单元测试 (XmlFrameDecoderTest.testDecodeWithXml()) 的泄漏:”

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

难怪这篇文章被各种不知道的来源转发了数十次,只是在没有测试的情况下复制粘贴单词。

*) Trustin Lee 建议在以下主题中的某些繁忙工作负载下运行应用程序 30 秒。 Netty 4/5 does not actually detect resource leak of bytebuf?但是,这不会为我触发检测或 ResourceLeakDetector 的任何输出。

*) 我还尝试了以下主题中建议的 GC 技巧 How to force garbage collection in Java?但这也没有任何区别。

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

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

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


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

到目前为止,对我而言,单元测试似乎对此毫无用处,除非您在单元测试中长时间运行全尺寸服务器(顺便说一下,这也不能保证任何事情,只是理论上会增加你的机会)。据我所知,没有充分的理由存在这种对测试的限制,但我们有我们拥有的。

互联网上有太多关于这个主题的令人困惑的信息,可悲的是,这些信息来自 Netty 文档本身,我真的希望以直截了当和清晰的方式陈述事实。

即使我的问题的答案是“这不可能”,仅提供此文本可能会为一些人节省大量的研究时间。


附言一个非常简单的示例来演示缺少输出。如果有人能告诉我需要进行哪些更改才能使此代码产生泄漏输出,我将不胜感激。

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

最佳答案

所以我设法让单元测试对我有用。

机制如下:

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

PooledByteBufAllocator alloc = new PooledByteBufAllocator(true, 1, 1, 8192, 11, 0, 0, 0);

2) 确保所有的 Bootstrap 都使用这个分配器

一个。客户端

Bootstrap clientBootstrap = new Bootstrap();
clientBootstrap.option(ChannelOption.ALLOCATOR, alloc);

服务器

ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.option(ChannelOption.ALLOCATOR, alloc)
.childOption(ChannelOption.ALLOCATOR, alloc);

3) 测试完成后,检查直接缓冲区和堆缓冲区的缓冲区泄漏

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;
}

关于java - 可用于单元测试的 Netty 4/5 确定性缓冲区泄漏检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37312091/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com