Keywords: System.OutOfMemoryException | ASP.NET | Memory Management | IIS Configuration | Debug Mode Optimization
Abstract: This paper provides an in-depth analysis of System.OutOfMemoryException in ASP.NET applications, focusing on memory management mechanisms, large object heap allocation issues, and the impact of application pool configuration on memory usage. Through practical case studies, it demonstrates how to effectively prevent and resolve memory overflow problems by cleaning temporary files, optimizing IIS configuration, and adjusting debug mode settings. The article also offers practical advice for large-scale data processing based on virtualization environment experiences.
Memory Exception Overview
System.OutOfMemoryException is a common runtime exception in the .NET framework, indicating that an application attempted to allocate resources exceeding available memory. In ASP.NET environments, this exception typically occurs during web request processing, especially when loading large datasets or performing complex operations.
Exception Generation Mechanism
From the stack trace, we can see the exception occurs during assembly loading:
System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective)
System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig)
This indicates the application attempts to load all referenced assemblies during startup. If an assembly is too large or memory is insufficient, the exception is triggered.
Primary Solutions
Cleaning Temporary Files
Accumulated cache files in system temporary folders may occupy significant memory space. Clean using these steps:
// C# Example: Clean temporary directory
string tempPath = Path.GetTempPath();
DirectoryInfo tempDir = new DirectoryInfo(tempPath);
foreach (FileInfo file in tempDir.GetFiles())
{
try
{
file.Delete();
}
catch (IOException ex)
{
// Handle file in use scenario
Console.WriteLine($"Cannot delete file {file.Name}: {ex.Message}");
}
}
Configuring IIS Express as 64-bit
32-bit applications have a 2GB memory limit, while 64-bit applications can access more memory. Configure in Visual Studio:
<!-- Web.config configuration example -->
<system.web>
<compilation targetFramework="4.8" />
<httpRuntime targetFramework="4.8" maxRequestLength="102400" />
</system.web>
Optimizing Debug Mode Settings
Memory management strategies differ in debug mode. Recommended to disable debugging in production:
<!-- Production Web.config configuration -->
<system.web>
<compilation debug="false" targetFramework="4.8" />
<httpRuntime enableVersionHeader="false" />
</system.web>
Special Considerations in Virtualization Environments
In VMware virtualization environments, large virtual machines may encounter similar issues. Reference cases show that storage snapshots and VMDK file alignment problems can cause memory exceptions:
// Best practices for large file processing
public void ProcessLargeFile(string filePath)
{
const int bufferSize = 81920; // 80KB buffer
byte[] buffer = new byte[bufferSize];
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using (BufferedStream bs = new BufferedStream(fs))
{
int bytesRead;
while ((bytesRead = bs.Read(buffer, 0, bufferSize)) > 0)
{
// Process data chunks, avoid loading entire file at once
ProcessDataChunk(buffer, bytesRead);
}
}
}
Memory Management Best Practices
1. Use using statements to ensure timely resource release
2. Avoid creating large objects in loops
3. Periodically call GC.Collect() to force garbage collection (use cautiously)
4. Monitor application pool memory usage
Performance Optimization Recommendations
For ASP.NET applications handling large data:
// Implement paged queries to avoid loading all data at once
public PagedResult<T> GetPagedData<T>(int pageIndex, int pageSize)
{
using (var context = new ApplicationDbContext())
{
var query = context.Set<T>().AsNoTracking();
var totalCount = query.Count();
var items = query.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.ToList();
return new PagedResult<T>
{
Items = items,
TotalCount = totalCount,
PageIndex = pageIndex,
PageSize = pageSize
};
}
}
Monitoring and Diagnostics
Use performance counters to monitor memory usage:
// Monitor application memory usage
PerformanceCounter ramCounter = new PerformanceCounter("Process", "Working Set", Process.GetCurrentProcess().ProcessName);
PerformanceCounter cpuCounter = new PerformanceCounter("Process", "% Processor Time", Process.GetCurrentProcess().ProcessName);
public void MonitorResources()
{
float ram = ramCounter.NextValue();
float cpu = cpuCounter.NextValue();
if (ram > 800 * 1024 * 1024) // Exceeds 800MB
{
// Trigger memory warning
LogMemoryWarning(ram);
}
}