当我使用Socket.IO,为什么我得到一个错误类型'System.OutOfMemoryException的'未处理的异常 [英] When I use Socket.IO, why I got an error An unhandled exception of type 'System.OutOfMemoryException'

查看:1961
本文介绍了当我使用Socket.IO,为什么我得到一个错误类型'System.OutOfMemoryException的'未处理的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我$ C $光盘的程序,以获得屏幕快照发送到服务器。每到这时,我得到了一个截图,变成的base64然后使用Socket.IO寄的。 (使用SocketIOClient.dll)

I coded a program to get the screen shot and send to the server. Every time, I got a screenshot and turned into base64 then sent it using Socket.IO. (using SocketIOClient.dll)

 Dictionary<string, string> image = new Dictionary<string, string>();
 image.add("image", "");

 private void windowMonitorTimer_Tick(object sender, EventArgs e)
 {

     image["image"] = windowMonitorManager.MonitorScreen();
     client.getSocket().Emit("Shot", image);
 }

windowMonitorManager.MonitorScreen()是返回一个base64字符串。如果我不使用 client.getSocket()的Emit(射击图片),该程序可以运行正确的,但如果我加入这一行,程序停止像2秒(发送近80倍),并给我的错误:

windowMonitorManager.MonitorScreen() is for return a base64 string. If I do not use client.getSocket().Emit("Shot", image), the program could run correct, but if I add this line, the program stop like 2 seconds(send nearly 80 times) and give me the error :

An unhandled exception of type 'System.OutOfMemoryException' occurred in mscorlib.dll

如果我不只要发送字符串,因为这,只有很短的字符串hello,它发送1600次则发生同样的问题。

If I do not send the string as long as this, just a short string "hello", it sends 1600 times then occurs the same problem.

有人知道如何调试这个问题?

Somebody knows how to debug this problem?

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

我尝试测试socket.Emit(),并发现它有它的极限。

I try to test socket.Emit(), and find it has its limit.

例如,我送1000万串,经过了88次,它发生了内存不足的问题。
如果我送的5000000串,历经170次,它发生同样的问题。

For example, I send a string of 10000000, after 88 times, it occurs the out of memory problem. If I send a string of 5000000, after 170 times, it occurs the same problem.

推荐答案

出的内存主要是抛出一个异常时,该过程消耗比默认情况下,系统(如2 GB在32位系统上)允许更大的内存,一个64位的系统上,它是较高的,但仍然是由某些实际限制的约束,这不是为2 ^ 64的理论值,它从操作系统的不同而不同的操作系统,并且还依赖于底层的RAM,但足够大的单一的过程,现在这种情况发生可以由于多种原因:

Out of memory is mostly an exception thrown when the process consumes much larger memory than what is allowed by default system (like 2 GB on a 32 bit system), on a 64 bit system, it is higher, but is still bound by the certain practical limit, it's not the theory value of 2^64, it differs from OS to OS and is also dependent on underlying RAM, but is large enough for a single process, now this situation can happens due to multiple reasons:


  • 内存泄漏(最突出的),主要是与非托管code的呼叫相关联,如果有未解除分配或释放手柄或存储器分配,经过一段时间其导致巨大存储器分配的过程,因此例外,当系统无法映射了。

  • Memory leak (most prominent), mostly associated with the unmanaged code calls, if there's a handle or memory allocation that is not de-allocated or freed, over a period of time it leads to huge memory allocation for a process and thus the exception, when system cannot map any more.

托管code能过泄漏,我已经做到了,当被不断创建的对象,他们不会去参考的,也就是说,它们仍然在GC背景下到达,所以你可能会导致这种情况下,我在code做到了这一点:)

Managed code can too leak and I have done that, when objects gets continuously created and they are not de-referenced, i.e they are still reachable in GC context, so you can lead to this scenario, I have done this in my code :)

这是不是空引用或损坏,因此采取直接堆栈跟踪会在这种情况下用处不大,只是因为你可能每次都获得不同的堆栈,它会像进程的堆栈螺纹,当发生异常,这将是大多是误导性的,所以不要尝试这种方式。执行一个线程的方法,但这并不意味着它造成内存泄漏,这将是不同的线程不同。

This is not a null reference or a corruption, so taking direct stack trace will be of little use in this scenario, simply because you may get a different stack every time, it will be like the stack of the process threads, when exception happens and it would be mostly misleading, so do not try that way. Executing method of a thread doesn't mean it caused memory leak and it will be different for different threads.

如何调试:

可以采取简单的步骤数来缩小,但任何事情之前,请确保您有对过程的所有加载的二进制有效PDB文件的调试版本。

Number of simple steps can be taken to narrow down, but before anything ensure that you have the debug version with valid pdb files for all the loaded binaries of the process.


  • 要知道它是一个泄漏,监控进程工作集,虚拟字节专柜或者通过任务管理器或通过性能监视器pferably $ P $,因为它是更准确,还提供可视化图

  • To know whether is it a leak, monitor process "working set", "virtual bytes" counters either via task manager or preferably via perfmon, since it is much more accurate, also it provides visual graph.

现在泄漏的泄漏,所以喜欢的地方默认的2 GB不仅可以帮助某个时候在32位系统升级到3 GB增加地址空间的步骤,但性能监视器会告诉你,如果有一个稳定点,就像在少数情况下,过程需要2.2 GB的内存,因此2 GB默认情况下是不够的,但3 GB的boot.config文件和USERVA设置进行微调3 GB将有助于避免例外。

Now a leak is a leak, so steps like increasing address space in a 32 bit system to 3 GB in place of default 2 GB can only help for sometime, but perfmon will tell you if there's a stabilization point, like in few cases, process needs 2.2 GB of memory, so 2 GB by default is not enough but 3 GB in boot.config and UserVA setting for fine tuning 3 GB will help avoiding exception.


  • 如果您使用的是64位系统,那么这是不是担心一点,但要确保你的二进制文件编译为X64或任何CPU,32位二进制运行作为WOW的过程,将有64位限制系统了。

  • If you are using 64 bit system then that's not a worry point, but ensure that your binary is compiled for X64 or any CPU, a 32 bit binary will run as a WOW process and will have limitation on 64 bit system too.

也可以尝试一个小工具,从Sysinternals的处理,在一个批次的过程将提供泄漏手柄的细节运行它复式倍,如文件,互斥等分配的句柄数量方面

Also try a small utility handles from sysinternals, running it mutliple times in a batch for a process will provide details of a leaking handle, in terms of number of handles like file, mutex etc allocated

一旦你确认一个真正的泄漏,而不是设置或配置或系统问题,然后是内存分析器。在免费的,你通过像的WinDbg,UMDH和leakdiag,他们INFACT点,你苛求这是泄漏的堆栈跟踪免费工具获得大量的信息。 UMDH和leakdiag都是很不错的工具,他们让你知道泄漏的功能。 Leakdiag比UMDH更为详尽,但对运行时堆UMDH是不够好

Once you have confirmed a genuine leak, not a settings or configuration or system issue, then comes the memory profilers. In free ones, you get lot of information through free tools like windbg, umdh and leakdiag, they infact point you to exact stack trace which is leaking. umdh and leakdiag are both very good tools, they let you know the leaking function. Leakdiag is more exhaustive than UMDH, but for runtime heap UMDH is good enough

专业内存分析器,如:

点记忆 - http://www.jetbrains.com/dotmemory/

也非常好,我个人觉得点存储更为有益的,它有助于迅速指向泄漏的功能或类型,毫不费力,只要你有正确的符号文件。两者都有免费下载版本。

are also very good, i personally find Dot memory much more helpful and it helps in quickly pointing to the leaking function or type, with little effort, provided you have correct symbol files. Both have free download version available

天色解决内存溢出异常是一个渐进的和反复的过程,因为这其中可能会在内心深处隐藏的,与泄漏每次​​执行一大块内存并把整个过程膝盖。让我知道如果你需要使用特定的工具帮助,那么我们可以看到更多的可以做进一步调试问题。快乐调试

Mostly resolving out of memory exception is a gradual and iterative process, because this one could be hidden deep inside, leaking a chunk memory with every execution and bringing the complete process to knees. Let me know if you need help in using a specific tool, then we can see what more can be done to debug the issue further. Happy Debugging

这篇关于当我使用Socket.IO,为什么我得到一个错误类型'System.OutOfMemoryException的'未处理的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆