views:

705

answers:

5

I have an ASP.Net MVC application that allows users to upload images. When I try to upload a really large file (400MB) I get an error.

I assumed that my image processing code (home brew) was very inefficient, so I decided I would try using a third party library to handle the image processing parts.

Because I'm using TDD, I wanted to first write a test that fails. But when I test the controller action with the same large file it is able to do all the image processing without any trouble.

The error I get is "Out of memory".

I'm sure my code is probably using a lot more memory than it needs to but I just want to know why my test passes.

The other difference is that I'm using SWFUpload which is not used with the test. Could this be the cause?

A: 

Where exactly does the exception originate from?

AFAIK there's no 400MB-caliber limit to image sizes in ASP.net/.Net. I'm writing a project where some files are much larger. There might be some higher limit I'm not aware of, of course, but it would seem odd and arbitrary.

Are you running on a 64 bit machine? Could your image file - uncompressed (is it 400MB in jpg?) - test the the 2GB limit of your process's address space?

Assaf Lavie
I'm on a 64bit machine. I think it comes from a Graphics.DrawImage(). I am creating a Bitmap form the file first and think that this is eating up the memory.
tpower
+4  A: 

There can be memory limits configured in either the web.config or machine.config, or both.

In web.config the section is:

<httpRuntime 
executionTimeout="3600" 
maxRequestLength="102400"
/>

In machine.config the section can also be the httpRunTime section, similar to:

<httpRuntime 
executionTimeout="90" 
maxRequestLength="4096"
useFullyQualifiedRedirectUrl="false" 
minFreeThreads="8" 
minLocalRequestFreeThreads="4"
appRequestQueueLimit="100"
/>

The aspnet process can also be limited to a percentage of the total memory using the processModel section, see:

http://msdn.microsoft.com/en-us/library/7w2sway1.aspx

I've encountered similiar problems to the one you described cause by those settings.
In particular the ProcessModel memorylimit attribute.

Bravax
The process model memory limit looks interesting but I can't find a machine.config on my dev machine. Shouldm't I have one?
tpower
It depends what version of the .net framework you're using.Try here: C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG
Bravax
+1  A: 

There is really no hard-limit for upload sizes. However, if you're on a 32-bit process, you may be limited by the amount of memory your asp.net worker process can address. Once it gets around 800mb, it becomes very unstable.

The timeout settings mentioned by Bravax are also a good place to check.

Cheers on using TDD!

Chris Ballance
A: 

You need to be sure to pipe data off the input stream into a filestream of some form so that the whole request entity isn't needed in memory.

AnthonyWJones
+1  A: 

From MSDN:

One way to guard against denial of service attacks is to limit the size of the files that can be uploaded by using the FileUpload control. You should set a size limit that is appropriate for the types of files that you expect to be uploaded. The default size limit is 4096 kilobytes (KB), or 4 megabytes (MB). You can allow larger files to be uploaded by setting the maxRequestLength attribute of the httpRuntime element. To increase the maximum allowable file size for the entire application, set the maxRequestLength attribute in the Web.config file. To increase the maximum allowable file size for a specified page, set the maxRequestLength attribute inside the location element in Web.config. For an example, see location Element (ASP.NET Settings Schema).

When uploading large files, a user might also receive the following error message:

aspnet_wp.exe (PID: 1520) was recycled because memory consumption exceeded 460 MB (60 percent of available RAM).

If your users encounter this error message, increase the value of the memoryLimit attribute in the processModel element of the Web.config file for the application. The memoryLimit attribute specifies the maximum amount of memory that a worker process can use. If the worker process exceeds the memoryLimit amount, a new process is created to replace it, and all current requests are reassigned to the new process.

flesh