다음을 통해 공유


Reducing Memory Usage with Large Messages

I'm working on an application that processes many large messages at the same time. The messages should all fit into memory, but I'm running out of memory much sooner than expected. How do I reduce the overhead associated with each message?

I'm only going to talk about the case where the system is legitimately running out of memory sooner than expected.

If you're trying to buffer messages that are larger than the memory you have available, then there is no clever trick to make those messages fit into memory. You will have to store all or part of the messages somewhere else, either by spooling to disk or by using streamed instead of buffered transfers.

If you're exceeding not the available memory but rather the available addressing space, then this similarly requires more fundamentally drastic approaches. A 32-bit machine can give roughly two billion address spaces to an application. Finding more than a few hundred million of these address spaces that are both free and consecutively located is a challenge. As you repeatedly allocate and free memory, fragmenting the free areas of addressing space, the challenge becomes larger and larger. That is a different problem than what this article is purporting to solve.

The specific case that is being talked about here is when the number of allocated buffer bytes consistently exceeds the number of actual message bytes by a significant margin. You may see this when, for example, you're processing a bunch of messages that occupy 12 megabytes of memory but sit inside of 16 megabyte buffers. This is the result of using a buffering system that is more appropriate for small message sizes.

When processing lots of small messages, the cost of allocating and freeing buffers can be noticeable relative to the amount of work that you're doing. Transports have two knobs, MaxBufferSize and MaxBufferPoolSize, to control this allocation strategy. When you're dealing with lots of large messages, then this pooling strategy doesn't save you that much time and can cost you some memory proportional to the message size. By setting MaxBufferPoolSize to 0, you eliminate this allocation overhead and raise the number of messages that you can process before running out of memory. Remember though, unless your messages are large, disabling buffer pooling tends to hurt more than it helps.

What are large messages? Certainly, if all of your messages are a few tens of megabytes in size, then you have large messages. If you regularly have messages that are a few tens of kilobytes in size, then you have small messages. If your messages are in-between or vary wildly in size, then you should experiment to see what is best for you.

Next time: Bindings for Workgroups

Comments

  • Anonymous
    February 01, 2007
    Today's article is about a classic flooding attack that relies on a receiver who isn't careful about

  • Anonymous
    February 19, 2007
    I haven't forgotten about the goal to put together a table of contents for all of these articles. The