我正在开发一个使用快速,持续的读/写循环与网络设备进行通信的C#,UWP 10解决方案. API提供的StreamSocket似乎工作得很好,直到我意识到内存泄漏:任务< uint32>在堆里,每分钟数百次.

我是否在一个异步任务中使用一个简单的(while)while(true)循环,或者使用一个自动发布的ActionBlock< T>使用TPL数据流(根据this answer),结果是一样的.

如果我消除了从套接字读取并专注于写入,我可以进一步隔离问题:
无论我使用DataWriter.StoreAsync方法还是使用更直接的StreamSocket.OutputStream.WriteAsync(IBuffer缓冲区),问题仍然存在.此外,将.AsTask()添加到这些没有什么区别.

即使垃圾收集器运行,这些Task< uint32>从来没有从堆中移除.所有这些任务都完成(RanToCompletion),没有任何错误或任何其他属性值,表示“不太准备回收”.

似乎有一个提示我的问题在this page(一个从托管到非托管世界的字节数组,防止释放内存),但规定的解决方案似乎很明显:唯一的办法是将所有通信逻辑写入C/C++X.我希望这不是真的肯定其他C#开发人员已经成功地实现了高速网络连续的连续通信,没有内存泄漏.当然,Microsoft不会发布一个仅在C/C++X中没有内存泄漏的API

编辑

根据要求,一些示例代码.我自己的代码层次太多,但可以观察到一个更简单的例子,this Microsoft sample.我做了一个简单的修改,在一个循环中发送1000次以突出显示问题.这是相关代码:

public sealed partial class Scenario3 : Page
{
    // some code omitted

    private async void SendHello_Click(object sender,RoutedEventArgs e)
    {
        // some code omitted

        StreamSocket socket = //get global object; socket is already connected

        DataWriter writer = new DataWriter(socket.OutputStream);

        for (int i = 0; i < 1000; i++)
        {
            string stringToSend = "Hello";
            writer.WriteUInt32(writer.MeasureString(stringToSend));
            writer.WriteString(stringToSend);
            await writer.StoreAsync();
        }
    }
}

启动应用程序并连接套接字后,只有Task< UInt32>的实例.在堆上点击“SendHello”按钮后,有86个实例.第二次按下之后:129次.

编辑#2
在运行我的应用程序(紧循环发送/接收)3个小时后,我可以看到,肯定有一个问题:50万个任务实例,从来没有得到GC,应用程序的进程内存从最初的46 MB增加到105 MB.显然这个程序不能无限期地运行.
但是,这只适用于在调试模式下运行.如果我在发布模式下编译我的应用程序,请将其部署并运行,没有内存问题.我可以把它整夜运行,很明显,正在正确地管理内存.
案件关闭.

解决方法

there are 86 instances. After pressing it a 2nd time: 129 instances.

这是完全正常的.还有一个强烈的提示,这里的真正问题是您不知道如何正确解释内存分析器报告.

任务听起来像一个非常昂贵的对象,它有很大的冲击力,一个线程涉及,你可以创建的最昂贵的操作系统对象.但是不是,一个Task对象实际上是一个惩罚对象.它在32位模式下只需要44字节,在64位模式下只有80字节.真正昂贵的资源不是由Task拥有,线程管理器负责处理.

这意味着您可以在GC堆上施加足够的压力以触发集合之前创建大量Task对象.其中约47,000人以32位模式填满第#0段.更多在服务器上,成千上万,其细分更大.

在您的代码片段中,Task对象是您实际创建的唯一对象.因此,您的for(;;)循环通常不能很好地循环,无法看到任务对象的数量减少或限制.

所以这是通常的故事,.NET框架有泄漏的指责,特别是在运行数月的服务器式应用程序中大量使用的这些基本对象类型,永远是夸张的.双重猜测垃圾收集器总是棘手的,您通常只会通过实际使您的应用程序运行几个月,永远不会在OOM失败获得信心.

c# – 为什么在循环中使用StreamSocket会导致内存泄漏?的更多相关文章

  1. ios – 为什么重复创建和删除SKShapeNode和SKNode导致内存泄漏?

    使用Xcode附带的spritekit模板,我修改场景如下:该应用程序似乎继续使用更多内存,直到它挂起或崩溃.使用泄漏和分配工具,我发现了以下内容:泄漏:分配:从图像中可以看出,存在大量使用内存的Malloc调用.我不直接调用Malloc–似乎这些调用是由SpriteKit完成的.同样,存在许多内存泄漏,这似乎也是由于SKShapeNode,SKNode或其他SpriteKit对象造成的.我如何解决或解决此内存(泄漏)问题?

  2. ios – Xcode显示内存泄漏,但仪器没有

    当我从Xcode运行我的应用程序时,很明显我有一个内存泄漏:当我提供一个自定义的ViewController时,内存增加,但是当我关闭它时,它不会退回.所以我也检查了使用仪器的分配工具,但这说明了一个不同的故事:可以看出,当我呈现ViewController时,仪器会显示尖峰,但是当内存使用被关闭时,内存使用率将恢复到以前的级别.我已经检查了我的代码至少15次,我个人无法找到任何内存泄漏,因此同意

  3. ios – 内存泄漏与UIWebView和Javascript

    清楚地包含一个Javascript文件到我的HTML是使UIWebView泄漏内存.当我重复使用相同的UIWebView对象时,或者每当我有内容实例化一个新的漏洞时,会出现泄漏的事实,导致我认为必须有一些JavaScript文件被loadHTMLString处理,导致泄漏.有人知道如何解决这个问题吗?

  4. ios – SBJson – 有内存泄漏?

    我刚刚克隆了SBJson框架的git存储库,并将源代码导入到我的应用程序中.跑了一个静态内存探查器,并从我看到的结果有点害怕.看图这怎么可能?我怀疑这个知名图书馆的开发者没有看到这个?事实上,如果运行内存配置文件,它会显示此库中的内存泄漏.有任何想法吗?

  5. 14.6 Swift中weak解决循环强引用

    /**循环强引用ARC不是万能的,它可以很好的解决内存过早释放的问题,但是在某些场合下不能很好的解决内存泄漏的问题。直接用官方例子*/classPerson{letname:Stringinit{self.name=name}varapartment:Apartment?这就是所谓的循环强引用*///这是强引用,不要认为可选类型就是弱引用啊,只有通过weakuNowned才是弱引用varjohn:Person?*//**在变量tenant前加上weak修饰,也就是将其中的一个变量设置为弱引用就行了。joh

  6. Swift闭包中的内存泄漏

    内存泄漏不仅破坏用户体验,而且会影响性能甚至应用的安全。既然内存泄漏如此的重要,所以这篇文章在这篇文章将说一说Swift闭包中的内存泄漏问题。Apple在文章中详细介绍了循环强引用的概念、何为内存泄漏、如何避免。内存泄漏的调试上面我们分析了大部分闭包中的循环引用问题,我们得知并不是所有的情况下都会导致内存泄漏。

  7. Android – 从低内存条件恢复

    我正在开发一个非常强烈的图像处理应用程序,我在水平FragmentStatePagerAdapter中有多个ListFragments.我积极地采用几乎每一个窍门和建议,我能够在这里和其他地方找到.我下载位图并将其保存到SD和软参考存储器缓存.然而,当我在某些时候使用该应用程序,我开始在LogCat中看到消息,就像下面一样如果我继续,上面的消息将变得更加迫切并且不可避免的应用程序将与OutOfMe

  8. Android内存泄漏的原因及解决技巧

    这篇文章主要介绍了Android内存泄漏的原因及解决技巧,帮助大家更好的利用Android进行开发,感兴趣的朋友可以了解下

  9. nodeJs内存泄漏问题详解

    由于内存泄漏在Node.js中非常的常见,可能在浏览器中应用javascript时,对于其内存泄漏不是特别敏感,但作为服务器语言运行时,你就不得不去考虑这些问题。

  10. vue中的eventBus会不会产生内存泄漏你知道吗

    这篇文章主要为大家详细介绍了vue中的eventBus会不会产生内存泄漏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

随机推荐

  1. c# – (wpf)Application.Current.Resources vs FindResource

    所以,我正在使用C#中的WPF创建一个GUI.它看起来像这样:它现在还没有完成.这两行是我尝试制作一种数据表,它们在XAML中是硬编码的.现在,我正在C#中实现添加新的水果按钮功能.我在XAML中有以下样式来控制行的背景图像应该是什么样子:因此,在代码中,我为每列col0,col1和col2创建一个图像,如果我使用以下代码,它添加了一个如下所示的新行:如你所见,它不太正确……为什么一个似乎忽略了一些属性而另一个没有?

  2. c# – 绑定DataGridTemplateColumn

    似乎我已经打了个墙,试图在DataGrid上使用DataTemplates.我想要做的是使用一个模板来显示每个单元格的两行文本.但是似乎无法以任何方式绑定列.以下代码希望显示我想做的事情.注意每个列的绑定:模板列没有这样的东西,因此,这个xaml不可能工作.我注定要将整个DataTemplate复制到每个列,只是对每个副本都有不同的约束?解决方法我不完全确定你想要做什么,但如果您需要获取整行的DataContext,可以使用RelativeSource绑定来移动视觉树.像这样:

  3. c# – 学习设计模式的资源

    最近我来到了这个设计模式的概念,并对此感到非常热情.你能建议一些帮助我深入设计模式的资源吗?

  4. c# – 是否有支持嵌入HTML页面的跨操作系统GUI框架?

    我想开发一个桌面应用程序来使用跨系统,是否有一个GUI框架,允许我为所有3个平台编写一次代码,并具有完全可脚本化的嵌入式Web组件?我需要它有一个API来在应用程序和网页之间进行交流.我知道C#,JavaScript和一些python.解决方法Qt有这样的事情QWebView.

  5. c# – 通过字符串在对象图中查找属性

    我试图使用任意字符串访问嵌套类结构的各个部分.给出以下(设计的)类:我想要从Person对象的一个实例的“PersonsAddress.HousePhone.Number”获取对象.目前我正在使用反思来做一些简单的递归查找,但是我希望有一些忍者有更好的想法.作为参考,这里是我开发的(crappy)方法:解决方法您可以简单地使用标准的.NETDataBinder.EvalMethod,像这样:

  6. c# – 文件下载后更新页面

    FamilyID=0a391abd-25c1-4fc0-919f-b21f31ab88b7&displaylang=en&pf=true它呈现该页面,然后使用以下元刷新标签来实际向用户提供要下载的文件:你可能需要在你的应用程序中做类似的事情.但是,如果您真的有兴趣在文件完全下载后执行某些操作,那么您的运气不佳,因为没有任何事件可以与浏览器进行通信.执行此操作的唯一方法是上传附件时使用的AJAXupload.

  7. c# – 如何在每个机器应用程序中实现单个实例?

    我必须限制我的.net4WPF应用程序,以便每台机器只能运行一次.请注意,我说每个机器,而不是每个会话.我使用一个简单的互斥体实现单实例应用程序,直到现在,但不幸的是,这样一个互斥是每个会话.有没有办法创建机器互连,还是有其他解决方案来实现每个机器应用程序的单个实例?

  8. c# – WCF和多个主机头

    我的雇主网站有多个主机名,都是同一个服务器,我们只是显示不同的皮肤来进行品牌宣传.不幸的是,在这种情况下,WCF似乎不能很好地工作.我试过overridingthedefaulthostwithacustomhostfactory.这不是一个可以接受的解决方案,因为它需要从所有主机工作,而不仅仅是1.我也看过thisblogpost,但是我无法让它工作,或者不是为了解决我的问题.我得到的错误是“这

  9. c# – ASP.NET MVC模型绑定与表单元素名称中的虚线

    我一直在搜索互联网,试图找到一种方式来容纳我的表单元素的破折号到ASP.NET的控制器在MVC2,3或甚至4中的默认模型绑定行为.作为一名前端开发人员,我更喜欢在我的CSS中使用camelCase或下划线进行破折号.在我的标记中,我想要做的是这样的:在控制器中,我会传入一个C#对象,看起来像这样:有没有办法通过一些正则表达式或其他行为来扩展Controller类来适应这种情况?我讨厌这样的事实,我必须这样做:甚至这个:思考?

  10. c# – 用户界面设计工具

    我正在寻找一个用户界面设计工具来显示文档中可能的GUI.我不能生成代码.我知道MicrosoftVisio提供了一个功能.但有什么办法吗?您使用哪种软件可视化GUI?

返回
顶部