我的程序是一个CRM,我使用Rad Ribbon Bar,所以有许多带图像的按钮,RadGridView(有些列包含图像)和许多其他包含图像的控件.这是一个mdi父/子计划.
在很多情况下,在加载mdi子项或使用某些网格视图时,程序将挂起并给我这个错误:
OutOfMemoryException occurred in System.Drawing.dll
Run Code Online (Sandbox Code Playgroud)
我试过GC.Collect()某些部分但没有成功.设置图像没有代码!例如,为按钮设置图像我在visual studio中使用了它的属性.我在可视模式下使用属性面板以这种方式设置了所有其他控制图像.
这些是与绘图相关的一些设计师代码:
btnCustomerList.Image = global::MyApp.Properties.Resources.CustomerList32;
gridViewCommandColumn1.Image = global::MyApp.Properties.Resources.ViewShop32;
Run Code Online (Sandbox Code Playgroud)
当使用应用程序一段时间后出现错误时,它将出现Program.cs在行中Application.Run(new MainForm());:
static void Main()
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", AppDomain.CurrentDomain.BaseDirectory + "\\Settings.config");
bool ok;
Mutex m = new Mutex(true, WindowsIdentity.GetCurrent().Name.ToString().Split('\\')[1] + "MyApp", out ok);
if (ok)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// The Error will cause HERE
Application.Run(new MainForm());
GC.KeepAlive(m);
}
else
Application.Exit();
}
Run Code Online (Sandbox Code Playgroud)
MainForm是包含功能区栏的mdi父级.这是完整的堆栈跟踪:
at System.Drawing.Image.FromHbitmap(IntPtr hbitmap, IntPtr hpalette)
at System.Drawing.Image.FromHbitmap(IntPtr hbitmap)
at System.Drawing.Icon.ToBitmap()
at System.Windows.Forms.ThreadExceptionDialog..ctor(Exception t)
at System.Windows.Forms.Application.ThreadContext.OnThreadException(Exception …Run Code Online (Sandbox Code Playgroud) 我有一个OutOfMemoryException,我想分析应该创建的数组的大小和类型.
我为这种情况创建了一个演示目的转储,我能够获得以下信息:
0:000> !pe
Exception object: 023f389c
Exception type: System.OutOfMemoryException
Message: <none>
InnerException: <none>
StackTrace (generated):
SP IP Function
0015EE44 0099007F OOM2!OOM2.Program.Main()+0xf
StackTraceString: <none>
HResult: 8007000e
0:000> !u 0099007F
Normal JIT generated code
OOM2.Program.Main()
Begin 00990070, size 22
00990070 baffffff7f mov edx,7FFFFFFFh
00990075 b90241a478 mov ecx,offset mscorlib_ni+0x4102 (78a44102)
0099007a e8192194ff call 002d2198 (JitHelp: CORINFO_HELP_NEWARR_1_VC)
>>> 0099007f 8bc8 mov ecx,eax
...
Run Code Online (Sandbox Code Playgroud)
所以我可以看到创建了一个新数组,大小为7FFFFFFF,这是20亿个项目.(请忽略这样一个事实:您甚至无法在32位.NET应用程序中创建该大小的byte [],因此在此示例中类型可能根本不重要.)
我现在已经读过数组的类型在ECX寄存器中,但遗憾的mscorlib_ni+0x4102 (78a44102)是不是很有帮助.
我尝试过!mln,!mdt甚至不切实际!ip2mt,但没有一个显示预期byte或byte[]输出.有没有办法从mscorlib的原生图像中获取类型?
我有一个应用程序,随着时间的推移创建了很多线程.我注意到内存使用量在运行时会增加并最终耗尽内存.但是同样的代码不会泄漏我同事环境中的内存.我们都有相同的.net版本.我能够使用以下示例代码重现该问题,该代码不会在我的同事的笔记本电脑上泄漏,而是在我的笔记本电脑上泄露.
public static void Main(string[] args)
{
Console.WriteLine("Version " + Environment.Version.ToString());
if (Environment.Is64BitProcess)
Console.WriteLine("64");
else
Console.WriteLine("32");
while(true)
{
Thread t = new Thread(() => { Thread.Sleep(1); });
t.IsBackground = true;
t.Start();
Thread.Sleep(1);
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行上面的内容时,会打印以下内容
Version 4.0.30319.18063
32
Run Code Online (Sandbox Code Playgroud)
在Visual Studio 2012中,项目的目标框架是.net framework 4.5.项目使用以下配置泄漏内存
Project Properties -> Build
Platform target: Any CPU
Prefer 32-bit: checked
Run Code Online (Sandbox Code Playgroud)
如果我取消选中Prefer 32-bit,它不会泄漏.
泄漏内存的另一种配置是
Project Properties -> Build
Platform target: x86
Prefer 32-bit: disabled
Run Code Online (Sandbox Code Playgroud)
由此产生的可执行文件泄露在我的笔记本电脑上并没有泄漏在我的同事的笔记本电脑上.
我使用CLR Profiler来查找内存泄漏,但它没有显示任何泄漏.但我确实看到Windows资源监视器中的工作集增加了大约1 MB /秒.
是什么导致我的环境中的32位模式的内存使用量增加,而不是我的同事?
问题背景
在过去的几个月里,我们发现我的在线 Asp.net 应用程序存在问题。应用程序工作正常,但一天内有 1 到 2 次突然在实时服务器上的不同模块上崩溃,但它们的代码根本不存在此类问题,并且在本地服务器上没有发现此类问题。
经过一些研究,我发现在实时服务器上的 IIS 上运行我的应用程序的进程其内存不断增加,当达到一定水平时,它开始崩溃。
临时解决方案:
每当我们发现此类问题时,我们都会在 IIS 上重新启动应用程序。它可以结束这个进程并开始新的进程,然后该应用程序开始工作。
一天中的某个时间,我们需要重新启动应用程序 2 到 3 次,有时甚至更多。
我发现的问题:内存泄漏。
经过一番研究后找到一些解决方案:
使用工具:Windbg
写命令
.load by clr
dumpheap -stat
Run Code Online (Sandbox Code Playgroud)显示大量数据类型的引用。现在我陷入了这一点。我在图片部分与您分享。
问题:
1. I am on the right direction in finding memory leaks issue?
2. if my path is right where whats my next step?
3. Windbg tool is good for finding such kind of issue?
Run Code Online (Sandbox Code Playgroud)
转储文件链接以进行详细审查,当服务器停止响应时我获取此转储文件
我在生产服务器上遇到了很多问题,但是我想在exe崩溃时用详细日志转储文件.
我找到了procdump工具.你能建议手动崩溃exe的代码c#,这样可以检查转储日志中获得的信息类型.
我正在将一些字节写入MemoryStream.我给它的大小为100 MB
using (MemoryStream Stream = new MemoryStream())
{
for ( loop 1400 time)
{
func(i, OStream, Stream, );
}
lock (this)
{
Stream.WriteTo(OStream);
}
Run Code Online (Sandbox Code Playgroud)
}
func(i, OStream, Stream)
{
loop 19 times
get buffer;
Stream.Write(buffer, 0, buffer.Length);
}
Run Code Online (Sandbox Code Playgroud)
缓冲区的byte[]大小从65536到116454不等.我循环1000次.我正在写for循环,但我得到OutOfMemoryException异常.
有没有办法扩展MemoryStream并避免异常?