首页 > 编程语言 >Troubleshoot Out of Memory issues In ASP.Net

Troubleshoot Out of Memory issues In ASP.Net

时间:2023-02-09 21:59:50浏览次数:70  
标签:ASP re Troubleshoot Memory large application memory NET your

Troubleshoot Out of Memory issues (System.OutOfMemoryException) in ASP.NET

This article helps you troubleshoot Out of Memory errors in ASP.NET.

Original product version:   ASP.NET
Original KB number:   2020006

Symptoms

One of the most common issues that we see in Microsoft Customer Support Services is OutOfMemoryException scenarios. So we've put together a collection of resources to help troubleshooting and identifying the cause of memory issues.

Before we cover the details of troubleshooting an OutOfMemoryException, it's important to understand what causes this problem. Contrary to what many developers believe, the amount of RAM that's installed doesn't impact the possibility of an OutOfMemoryException. A 32-bit operating system can address 4 GB of virtual address space, whatever the amount of physical memory that is installed in the box. Out of that, 2 GB is reserved for the operating system (Kernel-mode memory) and 2 GB is allocated to user-mode processes. The 2 GB allocated for Kernel-mode memory is shared among all processes, but each process gets its own 2 GB of user-mode address space. It all assumes that you aren't running with the /3gb switch enabled.

When an application needs to use memory, it reserves a chunk of the virtual address space and then commits memory from that chunk. It is exactly what the .NET Framework's garbage collector (GC) does when it needs memory to grow the managed heaps. When the GC needs a new segment for the small object heap (where objects smaller than 85 KB reside), it makes an allocation of 64 MB. When it needs a new segment for the large object heap, it makes an allocation of 16 MB. These large allocations must be satisfied from contiguous blocks of the 2 GB of address space that the process has to work with. If the operating system is unable to satisfy the GC's request for a contiguous block of memory, a System.OutOfMemoryException (OOM) occurs.

 Note

A 32-bit process running on a 64-bit operation system can address 4GB of user-mode memory, and a 64-bit process running on a 64-bit operation system can address 8TB of user-mode memory, so an OOM on a 64-bit operation system isn't likely. It is possible to experience an OOM in a 32-bit process running on a 64-bit operation system, but it usually doesn't occur until the process is using close to 3 GB of private bytes.

There are two reasons why you might see an OOM condition.

  1. Your process is using much memory (typically over 800 MB in a 32-bit environment.)
  2. The virtual address space is fragmented, reducing the likelihood that a large, contiguous allocation will succeed.

It's also possible to see an OOM condition because of a combination of 1 and 2. For more information, see Troubleshooting System.OutOfMemoryExceptions in ASP.NET.

When an OOM occurs, you may notice one or more of the following symptoms:

When it comes to determining the cause for an OOM condition, you're actually working to determine the cause for either a high memory situation or a fragmented address space. While we can't document all of the possible causes of these situations, there are some common causes that we see regularly.

The following information outlines common causes of OOM conditions and the resolutions on resolving each of these causes.

String concatenation

Strings in a managed application (an application written by using the .NET Framework) are immutable. When a new value is assigned to a string, a copy is made of the existing string. And the new value is assigned to the new string. It doesn't typically cause any problems. But when a large number of strings are concatenated, it ends up causing many more string allocations than a developer might realize. And it can lead to memory growth and OOM conditions.

To avoid OOM because of string concatenation, make sure that you're using the StringBuilder class. For more information, see How to improve string concatenation performance in Visual C#.

Fragmentation in the managed heap

The garbage collector (GC) in a managed application compacts the heaps to reduce the amount of fragmentation. However, it's possible to pin objects in a managed application. Pinned objects can't be moved during heap compaction. Doing so would change the address at which the object is located. If an application pins a large number of objects, and/or it pins objects for a long time, it can cause fragmentation in the managed heap. It can lead to the GC growing the managed heap more often and causing an OOM condition.

We've worked on minimizing OOM conditions because of pinning since the .NET Framework 1.0. Incremental improvements have been made in each version. However, there are still design patterns you can implement that will be beneficial if you have a need to pin objects.

Fragmentation in the Virtual Address (VA) space

Each process has a certain amount of memory allocated to it, and that memory represents the VA space for the process. If the VA space becomes fragmented, it increases the likelihood that the GC can't obtain a large block of contiguous memory to grow the managed heaps. And it can lead to an OOM condition.

Fragmentation in the VA space is often caused by one or more of the following scenarios:

  • Loading the same assemblies into multiple application domains.

    If you need to use an assembly in more than one application running in the same application pool, strong-name the assembly and install it into the GAC. By doing that, you ensure that the assembly is only loaded into the process one time.

  • Running an application in production with the debug attribute of the <compilation> element set to true.

    • The debug attribute of the <compilation> element should be false when in production.
    • You can use the <deploy retail="true" /> configuration to ensure that debug is always disabled in product. For more information, see deployment Element (ASP.NET Settings Schema).
  • Use of scripting within eXtensible Style sheet Language (XSL) transforms or creating XmlSerializers.

    In this case, dynamic assemblies caused by Extensible Style sheet Language Transformations (XSLT) scripting or XmlSerializers.

Return large sets of data

When using data from a database or other data source, it's important to limit the amount of data returned. For example, caching a query result that returns an entire database table to avoid the cost of retrieving parts of data from the database when needed isn't a good approach. Doing so can easily cause high memory and lead to an OOM condition. Allowing a user to start a similar query is another common way to create a high memory situation. For example, return all employees in a company or all customers in the state of Texas with a last name starting with the letter S.

Always limit the amount of data that can be returned from a database. Don't allow queries such as SELECT * FROM. . . because you then have no control over how much data is displayed in your page.

It's equally important to ensure that you aren't displaying a large data result in UI elements, such as the GridView control. Besides the memory required for the returned data, you'll also consume large amounts of data in strings and in UI elements that are required to render the results. By implementing paging and validating input so that large sets of data aren't returned, you can avoid this problem.

Run in a production environment with tracing enabled

ASP.NET tracing is a powerful feature for troubleshooting applications. But it should never be left on in a production environment. ASP.NET tracing uses data structures such as DataTables to store trace information, and over time, they can cause a high memory condition that can lead to OOM.

Tracing should be disabled in a production environment. You can do so by setting the enabled attribute of the <trace> element to false in your web.config file. Enabling retail deployment by using <deploy retail="true" /> also disables tracing in your applications.

Leak native resources

Many managed resources will also make use of native resources. Because the GC doesn't clean up native resources, a developer is responsible for implementing and calling the Dispose method to clean up native resources. If you're using a type that implements the IDisposable interface, and you don't call the Dispose method, you risk leaking native resources and causing an OOM condition.

These objects should implement the iDisposable interface and you should call the Dispose method on these objects when you no longer need them.

 

Quick things to check when you experience high memory levels in ASP.NET

This article describes the quick things to check when you experience high memory in Microsoft ASP.NET.

Original product version:   ASP.NET
Original KB number:   893660

This article will start with some common issues, actions to remedy these issues, and a brief explanation of why these situations can cause problems.

ASP.NET Support Voice column

In the April 2005 Support Voice column, we inadvertently provided a link to the wrong file. Instead of linking to a download for the Web service, we linked to the XML file returned by the Web service. That link has been corrected. If you'd like to review the article with the correct file attached, see Dynamic page updates using XMLHTTP.

What's considered high memory

Obviously, this question depends on volume and activity of specific applications. In general, high memory is when your ASP.NET worker process (Aspnet_wp.exe) or Internet Information Services (IIS) worker process (W3wp.exe) memory is consistently increasing and isn't returning to a comfortable level.

In general terms, a comfortable level would be under 600 MB in the default 2-GB user memory address space. Once the memory level is higher than that comfortable level, we're doing less than we should be. This behavior may affect other applications that are running on the system.

The key is to understand some applications require more memory than others. If you're exceeding these limits, you may add more memory or add another server to your Web farm (or consider a Web farm). Profiling is also recommended in these cases. It can enable developers to create leaner applications. In this article, we're looking at a situation where you consistently see memory rise until the server stops performing.

Application set up for debugging

One reason for high memory that we see here in Support a lot is when you have debugging, tracing, or both enabled for your application. Enabling debugging and tracing is a necessity when you develop your application. By default, when you create your application in Visual Studio .NET, you'll see the following attribute set in your Web.config file:

<compilation
 ...
 debug="true"
 />

or

 <trace
 enabled="true"
 ...
 />

Also, when you do a final build of your application, make sure that you do it in Release mode, not Debug mode. Once you're in production, debugging should no longer be necessary. It can really slow down your performance and eat up your memory. Setting this attribute means you change a few things about how you handle your application.

First, batch compile will be disabled, even if it's set in this compilation element. It means that you create an assembly for every page in your application so that you can break into it. These assemblies can be scattered randomly across your memory space, making it more difficult to find the contiguous space to allocate memory.

Second, the executionTimeout attribute (<httpRuntime> Element) is set to a high number, overriding the default of 90 seconds. It's fine when debugging, because you can't have the application time out while you patiently step through the code to find your blunders. However, it's a significant risk in production. It means that if you have a rogue request for whatever reason, it will hold on to a thread and continue any detrimental behavior for days rather than few minutes.

Finally, you'll be creating more files in your Temporary ASP.NET files folder. And the System.Diagnostics.DebuggableAttribute (System.Diagnostics Namespace gets added to all generated code, which can cause performance degradation.

If you get nothing else from this article, I do hope you get this information. Leaving debugging enabled is bad. We see this behavior all too often, and it's so easy to change. Remember it can be set at the page level. Make sure all of your pages aren't setting it.

String concatenation

There are applications that build HTML output by using server-side code and by just building one large HTML string to send to the browser. It's fine, but if you're building the string by using + and & concatenation, you may not be aware of how many large strings you're building. For example:

string mystring = "<html>";
mystring = mystring + "<table><tr><td>";
mystring = mystring + "First Cell";
mystring = mystring + "</td></tr></table>";
mystring = mystring + "</html>";

This code seems harmless enough, but here's what you're storing in memory:

<html>
<html><table><tr><td>
<html><table><tr><td>First Cell
<html><table><tr><td>First Cell</td></tr></table>
<html><table><tr><td>First Cell</td></tr></table></html>

You may think that you're just storing the last line, but you're storing all of these lines. You can see how it could get out of hand, especially when you're building a large table, perhaps by looping through a large recordset. If it's what you're doing, use our System.Text.StringBuilder class, so that you just store the one large string. See Use Visual C# to improve string concatenation performance

.NET Framework Service Pack 1 (SP1)

If you aren't running the .NET Framework SP1 yet, install this SP if you're experiencing memory issues. I won't go into great detail, but basically, with SP1 we're now allocating memory in a much more efficient manner. Basically, we're allocating 16 MB at a time for large objects rather than 64 MB at a time. We've all moved, and we all know that we can pack a lot more into a car or truck if we're using many small boxes rather than a few large boxes. It's the idea here.

Don't be afraid to recycle periodically

We recycle application pools in IIS every 29 hours by default. The Aspnet_wp.exe process will keep going until you end the task, restart IIS, or restart the computer. This behavior means that this process could be running for months. It's a good idea for some applications to just restart the worker process every couple of days or so, at a convenient time.

Questions to ask

The previous were all things that you can fix quickly. However, if you're experiencing memory issues, ask yourself these questions:

  • Am I using many large objects? More than 85,000 KB are stored in a large object heap.

  • Am I storing objects in Session state? These objects are going to stay in memory for much longer than if you use and dispose them.

  • Am I using the Cache object? When it's used wisely, it's a great benefit to performance. But when it's used unwisely, you wind up with much memory used that is never released.

  • Am I returning recordsets too large for a Web application? No one wants to look at 1,000 records on a Web page. You should be designing your application so that you never get more than 50 to 100 records in one trip.

Debugging

I won't get into setting up WinDbg. But you can use the following commands to see what exactly is in your memory, if you wish to troubleshoot more complicated issues.

!eeheap -gc

This command will show you how much managed memory you have. If this value is high, there's something that your managed code is building.

!dumpheap -stat

This command will take quite a while to run, even hours if your memory is large. But this command will give you a list of all of your objects, how many of each type, and how much memory each is using. (For example, for the StringBuilder class, you'll see many System.String objects)

Once you've found an object taking much memory, dig further by using the following command:

!do <addr>

You can get the address of the object you're looking for in the dumpheap command.

We'll be trying to incorporate more ways to use this diagnostic tool for specific situations in these columns. Let us know if we're doing a good job!

Memory and performance articles

Garbage Collector Basics and Performance Hints

Developing High-Performance ASP.NET Applications

ASP.NET Performance Monitoring, and When to Alert Administrators

Improving .NET Application Performance and Scalability

 
  • Troubleshooting native memory leak in an IIS 7.x Application Pool

    Debug Diagnostics 1.2 Performance Monitor Debugging Tools for Windows This material is provided for informational purposes only. Microsoft makes no warrantie...

  • Performance issues when you call web services - ASP.NET

    This article provides help to solve the performance issues that occur when you make calls to web services from an ASP.NET application.

  • gcServer Element - .NET Framework

    Learn more about: element

  • Debug a memory leak tutorial

    Learn how to debug a memory leak in .NET Core.


 

 

 

标签:ASP,re,Troubleshoot,Memory,large,application,memory,NET,your
From: https://www.cnblogs.com/ioriwellings/p/17107160.html

相关文章

  • ASP.NET Core+Element+SQL Server开发校园图书管理系统(完)
    随着技术的进步,跨平台开发已经成为了标配,在此大背景下,ASP.NETCore也应运而生。本文主要基于ASP.NETCore+Element+SqlServer开发一个校园图书管理系统为例,简述基于MVC三......
  • MemoryAnalyzer(MAT) 内存分析工具
    MemoryAnalyzer(MAT)内存分析工具启动指定JDK11+以上的版本进行启动(MAT必须要JDK11+才能成功启动):下载JDK11+(OpenJDK:https://jdk.java.net/19/)修改~/Mem......
  • kettle 报错 org.owasp.encoder
    在生成xml时候需要对密码加密处理也可以注释StringtransXml=transMeta.getXML();maven<dependency><groupId>org.owasp.esapi</groupId>......
  • vasp如何设置K点
    转载自:https://blog.shishiruqi.com//2019/04/25/kpoints/VASP的KPOINTS文件在VASP5.1.12以上版本中,KPOINTS文件可以缺省,k点信息写在INCAR里,但是不建议这么做:一是因为I......
  • ASP+VML制作统计图的源程序
    此程序只能用IE浏览器浏览,根据下面的源程序,我们只是略做修改结合数据库就能实际应用到一些系统中。示例:1、直方图    2、饼图   3、曲线图一、统计图--直方图<script......
  • Memory Layout of C++ Object in Different Scenarios
    http://www.vishalchovatiya.com/memory-layout-of-cpp-object/  Inthisarticle,wewillseethememorylayoutofdifferentC++Object.Andhowdifferents......
  • ASP.NET Core — IStartupFilter 与 IHostingStartup
    1.IStartupFilter  上面讲到的方式虽然能够根据不同环境将Startup中的启动逻辑进行分离,但是有些时候我们还会可以根据应用中的功能点将将一系列相关中间件的注册封装到......
  • ASP.NET Core—入口文件
    1.入口文件  一个应用程序总有一个入口文件,是应用启动代码开始执行的地方,这里往往也会涉及到应用的各种配置。当我们接触到一个新框架的时候,可以从入口文件入手,了解入......
  • ASP.NET Core 系列总结
    《ASP.NETCore系列总结》《ASP.NETCore》系列文章基于.NET3.1和.NET6,主要是系统总结自己日常工作和学习中的知识点,也供大家参考,希望大家都能够对ASP.NETCore......
  • 【.NET 8】ASP.NET Core计划 - 支持更完善的AOT发布
    .NET7.0刚发布不久,.NET社区开始了.NET8.0的开发,重心重新回到了新功能的迭代。我们知道在.NET7.0中一个令人激动的特新就是支持了NativeAOT,我们可以通过NativeAOT生成本机......