Channels ▼
RSS

Embedded Systems

Memory-Aware Components

Source Code Accompanies This Article. Download It Now.


Kirk is a software developer working in the Rational Software division of IBM. He can be contacted at kjkrauss@us.ibm.com.


Most software that runs out of memory simply crashes. On modern operating systems, this happens when programs require more virtual memory than is available. A program that reserves or commits too much virtual memory can run out of free space. When that happens, it can misbehave: Heap allocations may fail, new threads may not start, stacks may fail to grow, and so on. It might exit politely or crash at that point, often without so much as a complaint about what's really gone wrong.

Ideally, your programs gracefully handle out-of-memory conditions and keep running. At the least, they might provide some detailed diagnostic output, or find ways to cope with the situation and survive until resources become available again. Such positive outcomes are possible if the program can identify virtual memory that is not actually required at the time when the low-memory problem occurs. Given modern component-based programming techniques, the program's components typically don't have enough information about each other to understand and comply with one another's virtual memory requirements as the "memory pressure" builds. While the information-hiding aspect of good component-based design is useful in many ways, it can hamper the components' ability to share limited virtual memory resources.

There are two kinds of unused virtual memory that become interesting when your program is memory-starved:

  • Reserved virtual memory.
  • Unused committed virtual memory.

Reserved virtual memory occupies part of your program's virtual address space, most likely because a component has proactively set it aside, yet it is clearly not being used. Committed, but otherwise unused, virtual memory can be found when components aren't making prudent choices regarding their memory footprints. There's nothing that prevents a component from appropriating either reserved or unused committed virtual memory to prevent a crash, if your components have enough intelligence to recognize suitable ranges that might be appropriated. The appropriated ranges can be used to provide space for the preparation and presentation of diagnostic output, or for any other purpose required to keep your program running when it could not otherwise continue.

Some components proactively reserve virtual memory and don't use it. By reserving virtual memory, a component typically renders it unusable by other components of the same program that are running in the same process—unless the other components are "smart" enough to realize they could commit that memory for their own use, rather than cause a crash by running out of memory. You can build this sort of intelligence into your program, making your components smart enough to not die from out-of-memory conditions when reserved, uncommitted memory is available. To do that, you need a small virtual memory analyzer/watchdog component that records information about how virtual memory is used by your program. This information may include a set of timestamps recorded as the program runs, each time virtual memory is reserved. When virtual memory runs low, your other components might need your analyzer/watchdog component to grab the reserved memory region that has the oldest timestamp. The region is then available to be committed for whatever purpose necessary for the program to stay alive.

Some components proactively commit virtual memory and never use it. It may be left in an uninitialized state, or filled with a simple pattern—usually all NULLs. On most modern platforms, virtual memory is committed at least a page at a time (for example, a page occupies four kilobytes of virtual memory on most versions of Windows). Pages of memory left uninitialized can be decommitted by any component in a process, and no harm results unless the committed memory is actually needed by the component that originally committed it. The same virtual memory analyzer/watchdog component that monitors reserved virtual memory may be extended to make software components smart enough to not die from an out-of-memory condition whenever committed, uninitialized memory is available. The analysis can involve tracking the pages of memory as "in use" or "not in use." One way to tell whether a page is in use is to run a compression routine, such as the LZW algorithm, on the contents of the page. This can be done for each page tracked by your analyzer/watchdog component when an out-of-memory condition occurs and when reserved, uncommitted pages are unavailable. When all or part of a page is found to be initialized, the page can be considered in use. The analysis can also involve recording a timestamp, during the run, each time virtual memory pages are committed. When virtual memory runs low, your other components might need your analyzer/watchdog component to decommit the uninitialized page with the oldest timestamp, so that the page can be reused as needed to keep your program running.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video