source: proiecte/swift/trunk/lib/hoard-371/doc/heaplayers-article-cuj.htm @ 176

Last change on this file since 176 was 176, checked in by (none), 14 years ago
  • imported repo from "guagal"
File size: 63.7 KB
Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<!-- saved from url=(0098)http://devnet.developerpipeline.com/documents/s=9843/q=1/cuj0512alexandrescu/0512alexandrescu.html -->
3<HTML><HEAD><TITLE>Developer::Pipelines | Policy-Based Memory Allocation</TITLE>
4<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
5<META content=NOARCHIVE name=GOOGLEBOT>
6<META http-equiv=Description 
7content="The way your application allocates memory can have a dramatic effect on its performance. Modern general-purpose memory allocators are pretty efficient, but there's always room for improvement."><LINK 
8rev=Stylesheet href="heaplayers-article-cuj_files/pipelines_fonts.css" 
9type=text/css rel=Stylesheet><LINK rev=Stylesheet 
10href="heaplayers-article-cuj_files/pipelines_layout.css" type=text/css 
11rel=Stylesheet><LINK rev=Stylesheet 
12href="heaplayers-article-cuj_files/shared.css" rel=Stylesheet><LINK 
13rev=Stylesheet href="heaplayers-article-cuj_files/topics.css" rel=Stylesheet>
14<SCRIPT language=JavaScript1.2 src="heaplayers-article-cuj_files/stm31.js" 
15type=text/javascript></SCRIPT>
16<!-- pop up openscript -->
17<SCRIPT type=text/javascript>
18 function openScript(url, width, height) {
19        var Win = window.open(url,"openScript",'width=' + width +
20',height=' + height +
21',resizable=1,scrollbars=yes,menubar=yes,status=yes' );
22}
23 </SCRIPT>
24
25<META content="MSHTML 6.00.2900.2802" name=GENERATOR></HEAD>
26<BODY vLink=#003366 link=#003366 bgColor=#ffffff leftMargin=0 topMargin=0 
27marginheight="0" marginwidth="0"><!-- SiteCatalyst code version: G.7.Copyright 1997-2004 Omniture, Inc. More info available athttp://www.omniture.com -->
28<SCRIPT language=JavaScript><!--/* You may give each page an identifying name, server, and channel onthe next lines. */
29var s_pageName="http://devnet.developerpipeline.com/cpp/cuj0512alexandrescu/"
30var s_server="devnet.developerpipeline.com"
31var s_channel="http://devnet.developerpipeline.com/cpp/"
32var s_pageType="/SDMG/Publications/CUJ|/SDMG/Languages/C++"
33var s_prop1="NO_USER"
34var s_prop2=""
35var s_prop3=""
36var s_prop4=""
37var s_prop5=""
38var s_prop6=""
39var s_prop7=""
40var s_prop8=""
41var s_prop9=""
42var s_prop10=""
43/* E-commerce Variables */
44var s_campaign=""
45var s_state=""
46var s_zip=""
47var s_events=""
48var s_products=""
49var s_purchaseID=""
50var s_eVar1=""
51var s_eVar2=""
52var s_eVar3=""
53var s_eVar4=""
54var s_eVar5=""
55var s_account="cmpdevnetdeveloperpipelinecom"
56/********* INSERT THE DOMAIN AND PATH TO YOUR CODE BELOW ************///--></SCRIPT>
57
58<SCRIPT language=JavaScript 
59src="heaplayers-article-cuj_files/s_code_remote.js"></SCRIPT>
60<!-- End SiteCatalyst code version: G.7. -->
61<DIV class=border>
62<TABLE cellSpacing=0 cellPadding=0 width=940 border=0>
63  <TBODY>
64  <TR>
65    <TD vAlign=top align=left><!-- top banner table -->
66      <TABLE cellSpacing=0 cellPadding=0 width=770 bgColor=#ffffff border=0>
67        <TBODY>
68        <TR>
69          <TD width=1 bgColor=#ffffff><IMG height=2 hspace=0 
70            src="heaplayers-article-cuj_files/blank.gif" width=1 border=0></TD>
71          <TD width=769 bgColor=#ffffff><IMG height=2 hspace=0 
72            src="heaplayers-article-cuj_files/blank.gif" width=769 
73        border=0></TD></TR>
74        <TR>
75          <TD width=1 bgColor=#ffffff><IMG height=94 hspace=0 
76            src="heaplayers-article-cuj_files/blank.gif" width=1 border=0></TD>
77          <TD align=middle width=769 bgColor=#ffffff><!-- TOP AD --><!-- AD: 'http://localhost:8085/html.ng/site=sdmg&affiliate=sdmgdeveloperpipeline&pagepos=top&catid=&site_section=9843&articleid=141768&target=cpp&country=&state=' --><!-- Sniffer Code for Flash version=60 -->
78            <SCRIPT language=JavaScript>
79<!--
80var swf_click = "http://as.cmpnet.com/event.ng/Type=click&FlightID=45537&AdID=80364&TargetID=4722&Segments=1411,3108,3448,4875,5817,5871&Targets=2625,2878,4667,4722&Values=34,46,51,63,77,83,90,100,140,203,442,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&RawValues=&Redirect=http://www.intel.com/software/";
81var dcswf_click = escape(swf_click);
82var ShockMode = 0;
83var plugin = (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]) ? navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin : 0;
84
85if (plugin && parseInt(plugin.description.substring(plugin.description.indexOf(".")-1)) >= 6) 
86{
87ShockMode = 1;
88}
89else if (navigator.userAgent && navigator.userAgent.indexOf("MSIE")>=0 
90&& (navigator.userAgent.indexOf("Windows 95")>=0 || navigator.userAgent.indexOf("Windows 98")>=0 || navigator.userAgent.indexOf("Windows NT")>=0)) {
91document.write('<SCRIPT LANGUAGE=VBScript\> \n');
92document.write('on error resume next \n');
93document.write('ShockMode = (IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash.6")))\n');
94document.write('<\/SCRIPT\> \n');
95}
96if ( ShockMode ) {
97document.write('<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"');
98document.write(' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"');
99document.write(' ID=flashad WIDTH=728 HEIGHT=90>');
100document.write(' <PARAM NAME=movie VALUE="http://i.cmpnet.com/ads/graphics/as5/cc/flash/banner_728x90c_1209.swf?clickTag='+dcswf_click+'"> '); 
101document.write(' <PARAM NAME=quality VALUE=high> ');
102document.write(' <PARAM NAME=wmode VALUE=opaque> ');
103document.write(' <EMBED SRC="http://i.cmpnet.com/ads/graphics/as5/cc/flash/banner_728x90c_1209.swf?clickTag='+dcswf_click+'" QUALITY=high WMODE=opaque '); 
104document.write(' NAME=flashad swLiveConnect=TRUE WIDTH=728 HEIGHT=90');
105document.write(' TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">');
106document.write('</EMBED>');
107document.write('</OBJECT>');
108} else if (!(navigator.appName && navigator.appName.indexOf("Netscape")>=0 && navigator.appVersion.indexOf("2.")>=0)){
109document.write('<A HREF="http://as.cmpnet.com/event.ng/Type=click&FlightID=45537&AdID=80364&TargetID=4722&Segments=1411,3108,3448,4875,5817,5871&Targets=2625,2878,4667,4722&Values=34,46,51,63,77,83,90,100,140,203,442,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&RawValues=&Redirect=http://www.intel.com/software/" target="_top"><IMG SRC="http://i.cmpnet.com/ads/graphics/as5/cc/banner_728x90c.gif" WIDTH=728 HEIGHT=90 BORDER=0></A>');
110}
111//-->
112</SCRIPT>
113            <NOEMBED><A 
114            href="http://as.cmpnet.com/event.ng/Type=click&amp;FlightID=45537&amp;AdID=80364&amp;TargetID=4722&amp;Segments=1411,3108,3448,4875,5817,5871&amp;Targets=2625,2878,4667,4722&amp;Values=34,46,51,63,77,83,90,100,140,203,442,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&amp;RawValues=&amp;Redirect=http://www.intel.com/software/" 
115            target=_top><IMG height=90 
116            src="heaplayers-article-cuj_files/banner_728x90c.gif" width=728 
117            border=0></A> </NOEMBED><NOSCRIPT><A 
118            href="http://as.cmpnet.com/event.ng/Type=click&amp;FlightID=45537&amp;AdID=80364&amp;TargetID=4722&amp;Segments=1411,3108,3448,4875,5817,5871&amp;Targets=2625,2878,4667,4722&amp;Values=34,46,51,63,77,83,90,100,140,203,442,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&amp;RawValues=&amp;Redirect=http://www.intel.com/software/" 
119            target=_top><IMG height=90 
120            src="heaplayers-article-cuj_files/banner_728x90c.gif" width=728 
121            border=0></A> </NOSCRIPT><IMG height=1 src="" width=1 border=0> </TD>
122        <TR>
123          <TD width=1 bgColor=#ffffff><IMG height=3 hspace=0 
124            src="heaplayers-article-cuj_files/blank.gif" width=1 border=0></TD>
125          <TD width=769 bgColor=#ffffff><IMG height=3 hspace=0 
126            src="heaplayers-article-cuj_files/blank.gif" width=769 
127        border=0></TD></TR>
128        <TR>
129          <TD width=770 bgColor=#000066 colSpan=2><IMG height=2 hspace=0 
130            src="heaplayers-article-cuj_files/blank.gif" width=770 
131        border=0></TD></TR></TBODY></TABLE><!-- end top banner table --><!-- header table --><MAP 
132      id=header name=header><AREA shape=RECT coords=149,22,489,67 
133        href="http://www.developerpipeline.com/"></MAP>
134      <TABLE cellSpacing=0 cellPadding=0 width=770 bgColor=#ffffff border=0>
135        <TBODY>
136        <TR height=69>
137          <TD vAlign=top width=68><A href="http://www.cmp.com/"><IMG height=69 
138            hspace=0 src="heaplayers-article-cuj_files/cmp_logo.gif" width=68 
139            border=0></A></TD>
140          <TD vAlign=top><IMG height=69 
141            src="heaplayers-article-cuj_files/top_header.jpg" width=702 
142            useMap=#header border=0></TD></TR></TBODY></TABLE><!-- end header table --><!-- search/utility nav table -->
143      <TABLE cellSpacing=0 cellPadding=0 width=770 bgColor=#ffffff border=0>
144        <TBODY>
145        <TR>
146          <TD bgColor=#000066><IMG height=1 hspace=0 
147            src="heaplayers-article-cuj_files/blank.gif" width=1 border=0></TD>
148          <TD width=1 bgColor=#000066><IMG height=1 hspace=0 
149            src="heaplayers-article-cuj_files/blank.gif" width=1 border=0></TD>
150          <TD width=1 bgColor=#ffffff><IMG height=1 hspace=0 
151            src="heaplayers-article-cuj_files/blank.gif" width=1 border=0></TD>
152          <TD width=1 bgColor=#000066><IMG height=1 hspace=0 
153            src="heaplayers-article-cuj_files/blank.gif" width=1 border=0></TD>
154          <TD bgColor=#000066><IMG height=1 hspace=0 
155            src="heaplayers-article-cuj_files/blank.gif" width=1 border=0></TD></TR>
156        <TR>
157          <TD><SPAN class=side><SPAN class=black12Bold>Developer Network
158            Partners:</SPAN> <IMG height=1 hspace=0 
159            src="heaplayers-article-cuj_files/blank.gif" width=10 border=0> <A 
160            class=black12Bold href="http://www.cuj.com/">C/C++ Users Journal</A> 
161            <IMG height=8 hspace=0 src="heaplayers-article-cuj_files/blank.gif" 
162            width=10 border=0> <A class=black12Bold 
163            href="http://www.ddj.com/">Dr. Dobb's Journal</A> <IMG height=1 
164            hspace=0 src="heaplayers-article-cuj_files/blank.gif" width=10 
165            border=0> <A class=black12Bold 
166            href="http://www.sdmagazine.com/">Software Development</A> 
167</SPAN></TD>
168          <TD width=1 bgColor=#000066><IMG height=1 hspace=0 
169            src="heaplayers-article-cuj_files/blank.gif" width=1 border=0></TD>
170          <TD width=1 bgColor=#ffffff><IMG height=1 hspace=0 
171            src="heaplayers-article-cuj_files/blank.gif" width=1 border=0></TD>
172          <TD width=1 bgColor=#000066><IMG height=1 hspace=0 
173            src="heaplayers-article-cuj_files/blank.gif" width=1 border=0></TD><!-- UTILITY NAV -->
174          <TD align=middle><SPAN class=side><A class=black12Bold 
175            href="http://www.developerpipeline.com/contact.jhtml">Contact Us</A> 
176            <IMG height=8 hspace=0 src="heaplayers-article-cuj_files/blank.gif" 
177            width=18 border=0> <A class=black12Bold 
178            href="http://www.developerpipeline.com/about.jhtml">About Us</A> 
179            </SPAN></TD></TR></TBODY></TABLE><!-- end utility nav table --><!-- MAIN NAVIGATION TABS -->
180      <TABLE cellSpacing=0 cellPadding=0 width=770 bgColor=#ffffff border=0 
181      table_name="topNavigationTable">
182        <TBODY>
183        <TR>
184          <TD><A href="http://www.developerpipeline.com/news"><IMG height=29 
185            hspace=0 src="heaplayers-article-cuj_files/nav_news_dp.gif" 
186            border=0></A></TD>
187          <TD><A href="http://www.developerpipeline.com/trends"><IMG height=29 
188            hspace=0 src="heaplayers-article-cuj_files/nav_trends_dp.gif" 
189            border=0></A></TD>
190          <TD><A href="http://www.developerpipeline.com/howto"><IMG height=29 
191            hspace=0 src="heaplayers-article-cuj_files/nav_howto_dp.gif" 
192            border=0></A></TD>
193          <TD><A href="http://productfinder.developerpipeline.com/"><IMG 
194            height=29 hspace=0 
195            src="heaplayers-article-cuj_files/nav_productfinder_dp.gif" 
196            border=0></A></TD>
197          <TD><A href="http://www.developerpipeline.com/coding"><IMG height=29 
198            alt="Coding &amp; Scripting" hspace=0 
199            src="heaplayers-article-cuj_files/nav_coding_dp.gif" 
200border=0></A></TD>
201          <TD><A href="http://www.developerpipeline.com/design"><IMG height=29 
202            alt="Design &amp; Process" hspace=0 
203            src="heaplayers-article-cuj_files/nav_design_dp.gif" 
204border=0></A></TD>
205          <TD><A href="http://www.developerpipeline.com/tools"><IMG height=29 
206            alt=Tools hspace=0 
207            src="heaplayers-article-cuj_files/nav_tools_dp.gif" border=0></A></TD>
208          <TD><A href="http://www.developerpipeline.com/business"><IMG 
209            height=29 alt="Business &amp; Careers" hspace=0 
210            src="heaplayers-article-cuj_files/nav_business_dp.gif" 
211          border=0></A></TD></TR></TBODY></TABLE><!-- END MAIN NAVIGATION TABS --><!-- user notification table --><!--
212                 <br>
213                <table border="0" cellpadding="2" cellspacing="1" bgcolor="CC6600">
214  <tr>
215    <td bgcolor="FFD673">Some content requires registration to the CMP Developer Network.
216      Sign up today!.</td>
217  </tr>
218</table>
219--><!-- end user notification table --><!-- MAIN CONTENT TABLE -->
220      <TABLE cellSpacing=0 cellPadding=0 width=770 bgColor=#ffffff border=0>
221        <TBODY>
222        <TR>
223          <TD><IMG height=1 hspace=0 
224            src="heaplayers-article-cuj_files/blank.gif" width=1 border=0></TD></TR>
225        <TR>
226          <TD>
227            <TABLE cellSpacing=0 cellPadding=5 width="100%" border=0>
228              <TBODY>
229              <TR vAlign=top>
230                <TD><A 
231                  href="http://devnet.developerpipeline.com/">Developer::Pipelines</A> 
232                  &gt; <A 
233                  href="http://devnet.developerpipeline.com/cpp/">C++</A><BR><BR></TD>
234                <TD>&nbsp;</TD>
235                <TD align=right><!-- log in --><!--
236<a href='https://www.sdmediagroup.com/reg/?site=devnet.developerpipeline.com&content=http://devnet.developerpipeline.com/'><b>LOG IN</b></a> &#8226;
237<a href=/resetpassword.html>Forgot password?</a> &#8226;
238<a href=http://www.sdmediagroup.com/reg/faq.html>Registration FAQ</a> <br>
239--><!-- end log in --><!--
240<a href="javascript:openScript('http://www.sdmediagroup.com/reg/faq.html#compare',650,480)"><img src="/images/new/premium_bullet.gif" hspace="0" vspace="0" border="0"></a> Denotes content for All Access members only
241--></TD></TR></TBODY></TABLE></TD></TR>
242        <TR>
243          <TD vAlign=top align=left><!-- jumbobox ad --><!-- <table border="0" align="right" cellpadding="5" cellspacing="0">
244                          <tr>
245                          <td>
246                          <mpdoc:Ad group="sdmg" site="sdmgdeveloperpipeline" pagepos="jumbobox" documentsonly="true" spot="jumbobox">
247                          </td>
248                          </tr>
249                          </table>--><!-- end jumbobox ad --><!-- IMG height=40 hspace=5 src="java.gif" vspace=5 width=460 -->
250            <H1><FONT color=#5f92c7>Developer::</FONT>C++ Pipeline</H1><!-- -------- BEGIN Nav Anchors -->
251            <P><A class=header 
252            href="http://devnet.developerpipeline.com/cpp/index.html#articles">Articles</A> 
253            | <A class=header 
254            href="http://devnet.developerpipeline.com/cpp/index.html#books">Books</A> 
255            | <A class=header 
256            href="http://devnet.developerpipeline.com/cpp/index.html#showcase">Products</A> 
257            | <A class=header 
258            href="http://devnet.developerpipeline.com/cpp/index.html#papers">Whitepapers</A> 
259            | <A class=header 
260            href="http://devnet.developerpipeline.com/cpp/index.html#events">Training/Conferences</A> 
261            | <A class=header 
262            href="http://devnet.developerpipeline.com/cpp/index.html#forum">Discussion
263            Forum</A> | <A class=header 
264            href="http://syndication.sdmediagroup.com/feeds/public/cmp_devnet_c++.xml">C++
265            RSS Feed </A></P><!-- -------- END Nav Anchors --><!-- -------- BEGIN Vendor --><!-- AD: 'http://localhost:8085/html.ng/site=sdmg&affiliate=sdmgdeveloperpipeline&pagepos=logo&catid=&site_section=9843&articleid=141768&target=cpp&country=&state=' --><A>This
266            Pipeline Sponsored By:&nbsp;</A><A 
267            href="http://as.cmpnet.com/event.ng/Type=click&amp;FlightID=45541&amp;AdID=75588&amp;TargetID=4729&amp;Segments=1411,3108,3448,4875,5825,5867&amp;Targets=2625,2878,4729&amp;Values=34,46,51,63,77,83,90,100,140,442,618,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&amp;RawValues=&amp;Redirect=http://www.intel.com/"><IMG 
268            src="heaplayers-article-cuj_files/intel_logo2.gif" align=middle 
269            border=0></A><IMG height=1 src="" width=1 border=0> 
270            <HR align=left noShade SIZE=1>
271<!-- ---------- End Vendor --><!-- jumbobox ad -->
272            <TABLE cellSpacing=0 cellPadding=5 align=right border=0>
273              <TBODY>
274              <TR>
275                <TD><!-- AD: 'http://localhost:8085/html.ng/site=sdmg&affiliate=sdmgdeveloperpipeline&pagepos=jumbobox&catid=&site_section=9843&articleid=141768&target=cpp&country=&state=' --><A 
276                  href="http://as.cmpnet.com/event.ng/Type=click&amp;FlightID=45540&amp;AdID=75586&amp;TargetID=4718&amp;Segments=1411,3108,3448,4569,4875,5819,5866&amp;Targets=2625,2878,3885,4665,4718&amp;Values=34,46,51,63,77,83,90,100,140,290,442,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&amp;RawValues=IP,127.0.0.1,&amp;Redirect=http://" 
277                  target=_parent><IMG height=1 alt="" 
278                  src="C:\home\emery\projects\heaplayers\doc\heaplayers-article-cuj_files\blank(1).gif" 
279                  width=1 border=0></A><IMG height=1 src="" width=1 border=0> 
280              </TD></TR></TBODY></TABLE><!-- end jumbobox ad --><!--Copyright &#169; C/C++ Users Journal-->
281            <P><I>C/C++ Users Journal</I> December, 2005</P>
282            <H1>Policy-Based Memory Allocation</H1>
283            <H2>Fine-tuning your memory management</H2>
284            <H3>By Andrei Alexandrescu and Emery Berger</H3><I>Andrei
285            Alexandrescu is a graduate student in Computer Science at the
286            University of Washington and author of Modern C++ Design. He can be
287            contacted at andrei@metalanguage.com.</I> 
288            <HR>
289
290            <P>One of the perks of doing hard work for next to no money, an
291            activity also known as being a graduate student, is that you get to
292            rub shoulders with researchers working on interesting problems. I've
293            had the pleasure of meeting in person both Emery Berger and Kathryn
294            McKinley, two of the authors (with Benjamin Zorn) of "Composing
295            High-Performance Memory Allocators" [6], a paper that I found highly
296            interesting for "I can't believe I didn't think of that" reasons.
297            But let's start at the beginning.</P>
298            <P>One chapter of <I>Modern C++ Design</I> [2] is somewhat different
299            than all the others. Actually, very different. While the book is
300            dedicated to creating elegant, flexible, extensible designs, one
301            chapter stands out like a sore thumb by actually describing one
302            fixed, monolithic, rigid, awkward piece of software: Loki's small
303            object allocator. Somehow, I thought that memory management was a
304            low-level operation and, as such, didn't lend itself to the elegant
305            exploits of policy-based design. At the same time, some of the
306            compiler-provided <B>new</B>/<B>delete</B> implementations were
307            pretty bad at dealing with small objects, so I felt there would be a
308            need for something to fill the void. So I sat down and wrote an
309            implementation that has portability as its only merit; other than
310            that, it's not particularly performant, interesting, or original.
311            The main problem with Loki's allocator, however, does not lie in its
312            implementation (which, by the way, has been entirely rewritten by
313            Rich Sposato, to the end of greatly improving its performance), but
314            in its design, which is not configurable nor extensible—just a few
315            monolithic classes, much like what you'd expect in the bad ol'
316            days.</P>
317            <P>However, at about the same time, Emery Berger and others were
318            experimenting with a mixin-based memory allocator for C++ that is at
319            the same time highly efficient (rivaling the best general-purpose
320            allocators out there), highly customizable (rivaling the best
321            special-purpose allocators, too), and highly portable by virtue of
322            its customizable design! As soon as I became acquainted with that
323            research, I realized what the chapter on memory allocation in
324            <I>Modern C++ Design</I> should have looked like.</P>
325            <P>But before we delve into the fascinating topic of configurable
326            memory allocation, let's tie a few knots with past comments received
327            via e-mail.</P>
328            <H3>Mailcontainer</H3>
329            <P>I wrote the sidebar "Memory: More Than Just Any Resource" in the
330            last Generic&lt;Programming&gt; installment with the serene
331            resignation with which Galileo Galilei must have said his famous
332            "Eppur si muove." "And yet, garbage is collectable," I mumbled into
333            my three-days beard when submitting the article for publication. The
334            expected outcome was that the opponents of garbage collection would
335            exemplarily mortify me via an endless flow of angry e-mails.
336            However, they must've chosen instead to boycott me, because I
337            haven't gotten a single response in protest.</P>
338            <P>Ivan Godard sent me an e-mail on the subject of Observers [3, 4].
339            That message was so smart, and had me look up words in the
340            dictionary so often, that I've decided to quote it almost in
341            entirety, at the risk of blowing up the size of this article:</P>
342            <BLOCKQUOTE>Your difficulties with <B>attach</B> and <B>detach</B> 
343              while in the middle of notification are canonical concurrency
344              problems, and can be dealt with in the usual way. The (only
345              reasonable?) semantics for Observer is to see <B>subject</B>,
346              <B>observer</B>, and <B>event</B> as three independent and
347              asynchronous processes, with a time stream localized at
348              <B>subject</B>. That is, an <B>observer</B> cannot directly
349              determine the time relation between its attempt to attach and the
350              occurrence of a particular event because the event is not within
351              the observer's horizon. Only the <B>subject</B>, which receives
352              both events and requests to <B>attach</B>, can time-order
353              these.<BR><BR>Consequently a putative observer will see some
354              sequence of events that (in the subject's time frame) begins some
355              time after the attempt to attach and ends some time after the
356              attempt to detach. The sequence is guaranteed to be ordered (in
357              subject time) and dense, but where it starts and where it ends is
358              not known. Of course, if the observer is itself a source of events
359              and the channel between observer and subject is order-preserving,
360              then the observer can enforce somewhat more stringent bounds on
361              how far the observed sequence extends into the subject's past or
362              subject's future by injecting an event just before the attach or
363              just after the detach.<BR><BR>So much for relativity theory. In
364              practice, this implements naturally by considering the attempt to
365              attach and the attempt to detach as being themselves events. The
366              subject enqueues an event (including an <B>attach</B>/
367              <B>detach</B>) on an action list, and walks the list of observers
368              applying each event in turn to each observer. Both observers and
369              events are timestamped; a simple counter will do. Events are
370              discarded when there are no observers with lesser stamps. The
371              observer list is preceded by an observer (the subject itself) that
372              is watching for attach events and that adds the observer to the
373              observer list. All observers are watching for their own detach
374              events and remove themselves when the subject applies the
375              corresponding detach event. [...]<BR><BR>Most of the difficulties
376              you encountered appear to be a consequence of the assumption that
377              attach and detach were somehow global and absolute, rather than
378              just another event in the sequence of events encountered by the
379              subject. Remove that mistaken idea and your invalidated-iterators
380              problems disappear.<BR></BLOCKQUOTE>
381            <P>This view of attachment and detachment as simple events is very
382            interesting. This generalization would, however, make it harder to
383            define policies that lead to the simple implementations in the
384            article. Let's admit, such simple solutions are widely used and have
385            their place in spite of their risks and limitations. If anyone would
386            like to embark on defining a policy-based design for such a
387            "relativistic" Observer, and if the design does allow efficient
388            simple implementations as well, I'd be highly interested. Contact
389            Ivan at igodard@pacbell.net with questions.</P>
390            <P>Brian Wood comments on the "Walking Down Memory Lane"
391article:</P>
392            <BLOCKQUOTE>While you introduce <B>auto_vector</B>, you didn't
393              mention either of the <B>ptr_vector</B> implementations. Thorsten
394              Ottosen has written an interesting article about <B>ptr_vector</B> 
395              in the October 2005 issue of <I>Dr. Dobb's Journal</I>.
396              <B>auto_vector</B> and the <B>ptr_vector</B> by Ottosen are
397              obviously closely related, but also have differences. Some mention
398              to <B>ptr_vector</B> and the differences would have been helpful,
399              I think.<BR><BR>Anyway, from my own experience, I agree with you
400              that things like <B>auto_vector</B> and <B>ptr_vector</B> are
401              often preferable to <B>vector&lt;shared_ptr&lt;T&gt; 
402            &gt;</B>.<BR></BLOCKQUOTE>
403            <P>Great, thanks Brian—and readership, consider yourself tipped on
404            where to look for more material related to scoped memory
405            management.</P>
406            <H3>Memory Allocation: One Size Doesn't Fit ll</H3>
407            <P>Today's general-purpose memory allocators have reached reasonable
408            speed and low fragmentation for a large category of programs.
409            However, in the memory-allocation realm, a little information can go
410            a long way. Application-specific information about allocation
411            patterns helps to implement specialized memory allocators that
412            heavily improve the bottom line of many high-performance
413            applications. Sometimes, as little intel as "Blocks of size 80 are
414            allocated more often than blocks of all other sizes," when properly
415            used (as we'll discuss soon), can incredibly improve the bottom-line
416            runtime of a program. (Caveat: Sometimes customized allocators are
417            no better, and can be worse, than general-purpose allocators—see the
418            paper "Reconsidering Custom Memory Allocation" [7] for more
419            details.) While general-purpose allocators have average overheads in
420            the hundreds of cycles, a good customized memory allocator can
421            require as few as half a dozen cycles.</P>
422            <P>That's why many high-profile, high-performance applications (GCC,
423            Apache, and Microsoft's SQL Server to name just a few) implement
424            their own memory allocator. A good idea, then, is to generalize such
425            good specialized allocators and put them in a library. But
426            "generalization" and "specialization" are in tension: Your
427            application might have different allocation patterns that would
428            require yet another behavior from your allocator. What to do?</P>
429            <P>But wait, there's more. If we do devise a method to easily create
430            special-purpose memory allocators, we can go full-circle and define
431            a general-purpose allocator as a combination of wisely chosen
432            special-purpose allocators. If the resulting general-purpose
433            allocator compares favorably with the existing monolithic
434            general-purpose allocators, then the design is valid and useful.</P>
435            <P>Emery's team worked towards that idea, leading to their library
436            HeapLayers (http://heaplayers.org/). To define configurable
437            allocators, they used mixins (also known as Coplien's curiously
438            recurring pattern in the C++ community): defining classes with a
439            parameterized base. Each layer defines only two member functions,
440            <B>malloc</B> and <B>free</B>:</P><PRE>template &lt;class T&gt;
441struct Allocator : public T {
442  void * malloc(size_t sz);
443  void free(void* p);
444  // system-dependent value
445  enum { Alignment = sizeof(double) };
446  // optional interface
447  size_t getSize(const void* p);
448};
449
450</PRE>
451            <P>Each layer implementation would get a crack on allocation and
452            deallocation, possibly (and likely) requesting memory from its base
453            class. A self-contained allocator sits at the very top of the
454            hierarchy—one that forwards requests straight to the system's
455            <B>new</B> and <B>delete</B> operators, <B>malloc</B> and
456            <B>free</B> functions, and the such. In HeapLayers terminology,
457            these are the top heaps. To exemplify (careful with the
458            qualifications so we don't enter infinite recursion):</P><PRE>struct MallocHeap {
459  void * malloc(size_t sz) {
460    return std::malloc(sz);
461  }
462  void free(void* p) {
463    return std::free(p);
464  }
465};
466
467</PRE>
468            <P>Top heaps can also be implemented around system calls for getting
469            memory, such as UNIX's <B>sbrk</B> or <B>mmap</B>. This is necessary
470            when you're completely replacing <B>malloc</B> and friends.</P>
471            <P>The <B>getSize</B> function has a special status. Not everybody
472            is going to need it, so defining it is optional (if you combine the
473            wrong layers, the compiler will tell you). If it does, all you have
474            to do is insert a layer that stores the block size and offers the
475            <B>getSize</B> primitive; see <A 
476            href="http://devnet.developerpipeline.com/documents/s=9843/q=1/cuj0512alexandrescu/0512alexandrescul1.html" 
477            target=_BLANK>Listing 1</A>.</P>
478            <P><B>SizeHeap</B> is the perfect illustration of how to implement a
479            useful layer that hooks into its base's <B>malloc</B> and
480            <B>free</B> functions, does something extra, and returns "doctored"
481            results to the client. <B>SizeHeap</B> does its work by allocating
482            extra memory to store the block size, with the appropriate cautions
483            (the union) to stay as immune as possible to the alignment issue.
484            The client gets access to the memory right next to that extra data.
485            It's not hard to imagine building a debug heap that pads the memory
486            block before and after with some bytes filled with a particular
487            pattern, and then verify for overruns by checking whether the
488            pattern has been preserved. In fact, that's exactly what HeapLayers'
489            <B>DebugHeap</B> layer does. Pretty neat.</P>
490            <P>But wait, something's suboptimal here. Some systems already offer
491            a primitive to compute the size of a <B>malloc</B>ated block. On
492            those systems, <B>SizeHeap</B> would actually waste space. In that
493            case (for example, on Microsoft Visual C++), you wouldn't need
494            <B>SizeHeap</B> in conjunction with <B>MallocHeap</B>, because
495            <B>MallocHeap</B> would implement <B>getSize</B> out of the box:</P><PRE>struct MallocHeap {
496  ... as above ...
497  size_t getSize(void* p) {
498    return _msize(p);
499  }
500};
501
502</PRE>
503            <P>But wait, something's still suboptimal here. Remember, we're
504            counting cycles. What if a system's <B>malloc</B> documentation
505            states that the block size is stored in a word prior to the actual
506            block? In that case, <B>SizeHeap</B> would still waste memory by
507            storing yet another word next to the one already planted by the
508            system. What's needed is a layer that implements <B>getSize</B> just
509            the way <B>SizeHeap</B> does, but doesn't hook <B>malloc</B> and
510            <B>free</B>. That's why <B>HeapLayers</B> segregates the previously
511            shown <B>SizeHeap</B> in two; see <A 
512            href="http://devnet.developerpipeline.com/documents/s=9843/q=1/cuj0512alexandrescu/0512alexandrescul2.html" 
513            target=_BLANK>Listing 2</A>.</P>
514            <P>Now <B>SizeHeap</B> always (correctly) adds the
515            <B>UseSizeHeap</B> layer and exploits its <B>getSize</B> 
516            implementation, while <B>UseSizeHeap</B> can also be used in other
517            configurations—a very elegant design.</P>
518            <H3>A Useful Example: FreelistHeap</H3>
519            <P>Let's face it, so far we have kind of set up the stage. We do
520            have an architecture, but no clue on how to write an efficient
521            specialized allocator using layers. A popular and "most bang for the
522            buck" strategy is the following:</P>
523            <OL>
524              <LI>Collect stats about your application's allocation counts for
525              each size.
526              <LI>For the most often asked size (call it <B>S</B>), maintain a
527              private, singly linked list.
528              <LI>Memory allocations for <B>S</B> return memory from that list
529              if possible, or else from the default allocator (in a layered
530              architecture, from the superior layer).
531              <LI>Memory deallocations for blocks of size <B>S</B> push the
532              block into the list. </LI></OL>
533            <P>A refinement of the strategy would be to use the same free list
534            for a range of sizes <B>S1</B> to <B>S2</B>, at the cost of some
535            slack memory. The needed singly linked list operations are
536            <B>O(1)</B> and actually only a few instructions. In addition, the
537            pointer to the next item can be stored in the actual block (the
538            block stores no useful data—it's always a freed block!) so there's
539            no extra memory required per block. Given that most applications'
540            allocation size distribution is highly skewed, free lists are any
541            allocator implementer's indispensable utensil.</P>
542            <P>Let's implement a layer that implements a free list for a range
543            of statically known sizes <B>S1</B> to <B>S2</B>; see <A 
544            href="http://devnet.developerpipeline.com/documents/s=9843/q=1/cuj0512alexandrescu/0512alexandrescul3.html" 
545            target=_BLANK>Listing 3</A>.</P>
546            <P>Now you can define a custom heap like this:</P><PRE>typedef FLHeap&lt;
547  SizeHeap&lt;MallocHeap&gt;,
548  24,
549  32&gt;
550SmartoHeapo;
551
552</PRE>
553            <P><B>SmartoHeapo</B> will be superfast for allocation sizes between
554            24 and 32, and pretty much the same for all other sizes.</P>
555            <H3>In-Place Resizing</H3>
556            <P>Many a C++ programmer has been dreaming for a standard primitive
557            to reallocate memory in place. You see, C has <B>realloc</B>, which
558            can do in-place reallocation if possible, or use <B>memcpy</B> when
559            it comes about copying data around. But <B>memcpy</B> doesn't work
560            for C++ objects, so <B>realloc</B> doesn't work for C++ objects,;
561            therefore, any sort of renew primitive can't be implemented using
562            the Standard C allocator. So C++ doesn't have renew [1].</P>
563            <P>To give you an idea of the improvements that in-place
564            reallocation can bring to C++ code, consider:</P><PRE>const int n = 10000;
565Vec v;
566for (int i = 0; i &lt; n; ++i)
567  v.push_back(0);
568
569</PRE>
570            <P>Howard Hinnant of Metrowerks has been working on implementing
571            in-place expansion for CodeWarrior's Standard Library
572            implementation. In Howard's own words:</P>
573            <BLOCKQUOTE>I currently have a <B>vector&lt;T,
574              malloc_allocator&lt;T&gt; &gt;</B> that does [...] expand-in-place
575              based on N1085 [8]. It blows the doors off a built-in C-like
576              array! :-) When <B>Vec</B> is a <B>vector&lt;int&gt;</B> without
577              expand-in-place: <PRE>0.00095674 seconds</PRE>When <B>Vec</B> is a
578              <B>vector&lt;int&gt;</B> with expand-in-place: <PRE>0.000416943 seconds</PRE>The timings should only be trusted
579              to two significant digits. But rest assured, I've done the work to
580              secure those two digits. We are not looking at an anomaly here.
581            </BLOCKQUOTE><PRE></PRE>
582            <P>Given the benefits of in-place resizing and that each heap layer
583            has control over its own allocation algorithms and data structures,
584            let's augment the heap-layer interface:</P><PRE>template &lt;class T&gt;
585struct Allocator : public T {
586  void * malloc(size_t sz);
587  void free(void* p);
588  size_t expand(void* p, size_t min, size_t max);
589};
590
591</PRE>
592            <P>The semantics of expand is, try to expand the block pointed to by
593            <B>p</B> to the largest size possible between <B>min</B> and
594            <B>max</B>. Then return whatever size you could expand the memory
595            to, or zero if no expansion was possible. Fortunately, things can be
596            arranged such that a layer doesn't have to fuss about the expand
597            routine unless it wants to. That works if all top allocators inherit
598            the following little class:</P><PRE>struct TopHeap {
599  size_t expand(void*, size_t, size_t) {
600    return 0;
601  }
602  // not intended for standalone usage
603protected:
604  ~TopHeap() {}
605};
606
607</PRE>
608            <H3>Conclusion</H3>
609            <P>Configurable memory allocation is, as Emery's research has shown,
610            a practical, all-in-one alternative to both specialized and
611            general-purpose allocators. Emery's numbers (refer to the paper [6]
612            for details) consistently show that allocators created with
613            HeapLayers perform just as well as, or better than, monolithic
614            allocators, be they general-purpose or specialized. Moreover,
615            HeapLayers' layered architecture encourages easier experimentation,
616            simpler debugging, and unparalleled extensibility. Instead of being
617            an oddball chapter of <I>Modern C++ Design</I>, memory allocation
618            should have been one of the best success stories of policy-based
619            design.</P>
620            <P><A 
621            href="http://devnet.developerpipeline.com/documents/s=9843/q=1/cuj0512alexandrescu/0512alexandrescut1.html" 
622            target=_BLANK>Table 1</A> shows a relevant subset of the layers
623            implemented in HeapLayers. There would be a lot of goodies to
624            discuss, such as the locked heaps for multithreaded operations, the
625            STL adapter, the various utility heaps, or how the layers can be
626            combined to create a general-purpose allocator. But conventional
627            wisdom warns us that "The mind can only enjoy what the butt can
628            endure," so it's about time to shut down—without forgetting to
629            release the memory in destructors. Happy coding.</P>
630            <H3>References</H3>
631            <OL>
632              <LI>Alexandrescu, Andrei. "Generic&lt;Programming&gt;: Typed
633              Buffers (III)," <I>C++ Experts Online</I>, December 2001.
634              Available at http://erdani.org/ publications/cuj-12-2001.html.
635              <LI>Alexandrescu, Andrei. <I>Modern C++ Design</I>, Addison-Wesley
636              Longman, 2001.
637              <LI>Alexandrescu, Andrei. "Generic&lt;Programming&gt;: Prying
638              Eyes: A Policy-Based Observer (I)," <I>C++ Users Journal</I>,
639              April 2005.
640              <LI>Alexandrescu, Andrei. "Generic&lt;Programming&gt;: Prying
641              Eyes: A Policy-Based Observer (II)," <I>C++ Users Journal</I>,
642              June 2005.
643              <LI>Berger, Emery D., Kathryn S. McKinley, Robert D. Blumofe, and
644              Paul R. Wilson. "Hoard: A scalable memory allocator for
645              multithreaded applications. In International Conference on
646              Architectural Support for Programming Languages and Operating
647              Systems (ASPLOS-IX), pp. 117-128. Cambridge, MA, November 2000;
648              http://citeseer.ist.psu.edu/berger00hoard.html.
649              <LI>Berger, Emery D., Benjamin G. Zorn, and Kathryn S. McKinley.
650              "Composing High-Performance Memory Allocators," in SIGPLAN
651              Conference on Programming Language Design and Implementation, pp.
652              114-124, 2001; http://citeseer.ist.psu.edu/berger01composing.html.
653
654              <LI>Berger, Emery D., Benjamin G. Zorn, and Kathryn S. McKinley.
655              "Reconsidering custom memory allocation," in Proceedings of the
656              Conference on Object-Oriented Programming Systems, Languages, and
657              Applications (OOPSLA) 2002. Seattle, Washington, November 2002;
658              http://citeseer.ist.psu.edu/berger02reconsidering.html.
659              <LI>Hinnant, Howard. Proposal to augment the interface of
660              malloc/free/realloc/calloc. See
661              http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1085.htm.</LI></OL>
662            <H5>CUJ</H5>
663            <P>&nbsp;</P>
664            <TABLE cellSpacing=1 cellPadding=5 width="100%" bgColor=#000000 
665            border=0>
666              <TBODY>
667              <TR vAlign=top bgColor=#ffffff>
668                <TD width="50%"><!-- -------------------- BEGIN Forum --><A 
669                  class=header name=forum>From our C Discussion Forum</A><BR><A 
670                  href="http://devnet.developerpipeline.com/forums/thread.html?forumid=64&amp;threadid=23245">Serial
671                  USB support and code</A><BR><!MESSAGE!><BR><A 
672                  href="http://devnet.developerpipeline.com/forums/thread.html?forumid=64&amp;threadid=23242">ATA
673                  PC Card Identify Drive</A><BR><!MESSAGE!><BR><A 
674                  href="http://devnet.developerpipeline.com/forums/thread.html?forumid=64&amp;threadid=23239">need
675                  Mathematic lib source code </A><BR><!MESSAGE!><BR><A 
676                  href="http://devnet.developerpipeline.com/forums/forum.html?forumid=64">Visit
677                  the C Forum</A> <!-- -------------------- END Forum --></TD>
678                <TD width="50%"><A class=header>C++ related Articles</A> 
679                  <BR><B><A 
680                  href="http://devnet.developerpipeline.com/documents/s=9843/q=1/ddj050820pc/ddj050820pc.mp3">Eclipse
681                  CDT 3.0 Released</A></B><BR><BR></TD></TR></TBODY></TABLE></TD><!-- divider columns --></TR>
682        <TR>
683          <TD vAlign=top align=left height=10><IMG height=10 hspace=0 
684            src="heaplayers-article-cuj_files/blank.gif" width=770 
685        border=0></TD></TR></TBODY></TABLE><!-- END MAIN CONTENT TABLE --><!-- BOTTOM NAVIGATION -->
686      <TABLE cellSpacing=0 cellPadding=0 width=770 bgColor=#ffffff border=0 
687      table_name="footerTable">
688        <TBODY>
689        <TR>
690          <TD align=middle bgColor=#999999><IMG height=2 hspace=0 
691            src="heaplayers-article-cuj_files/blank.gif" width=770 
692        border=0></TD></TR>
693        <TR>
694          <TD>
695            <DIV class=BOTnav><A class=blacknavigation 
696            href="http://www.developerpipeline.comnews/">News</A> <IMG height=11 
697            hspace=5 src="heaplayers-article-cuj_files/orangeline.gif" width=2 
698            border=0 valign="absbottom"> <A class=blacknavigation 
699            href="http://www.developerpipeline.com/trends">Trends</A> <IMG 
700            height=11 hspace=5 src="heaplayers-article-cuj_files/orangeline.gif" 
701            width=2 border=0 valign="absbottom"> <A class=blacknavigation 
702            href="http://productfinder.developerpipeline.com/">Product
703            Finder</A> <IMG height=11 hspace=5 
704            src="heaplayers-article-cuj_files/orangeline.gif" width=2 border=0 
705            valign="absbottom"> <A class=blacknavigation 
706            href="http://www.developerpipeline.com/howto">How-To</A> <IMG 
707            height=11 hspace=5 src="heaplayers-article-cuj_files/orangeline.gif" 
708            width=2 border=0 valign="absbottom"> <A class=blacknavigation 
709            href="http://www.developerpipeline.com/coding">Coding &amp; 
710            Scripting</A> <IMG height=11 hspace=5 
711            src="heaplayers-article-cuj_files/orangeline.gif" width=2 border=0 
712            valign="absbottom"> <A class=blacknavigation 
713            href="http://www.developerpipeline.com/design">Design &amp; 
714            Process</A> <IMG height=11 hspace=5 
715            src="heaplayers-article-cuj_files/orangeline.gif" width=2 border=0 
716            valign="absbottom"> <A class=blacknavigation 
717            href="http://www.developerpipeline.com/tools">Tools</A> <IMG 
718            height=11 hspace=5 src="heaplayers-article-cuj_files/orangeline.gif" 
719            width=2 border=0 valign="absbottom"> <A class=blacknavigation 
720            href="http://www.developerpipeline.com/business">Business &amp; 
721            Careers</A> <BR><A class=blacknavigation 
722            href="http://www.developerpipeline.com/newsletter.jhtml">Free
723            Newsletters</A> <IMG height=11 hspace=5 
724            src="heaplayers-article-cuj_files/orangeline.gif" width=2 border=0 
725            valign="absbottom"> <A class=blacknavigation 
726            href="http://www.developerpipeline.com/glossary.jhtml">Developer
727            Glossary</A> <IMG height=11 hspace=5 
728            src="heaplayers-article-cuj_files/orangeline.gif" width=2 border=0 
729            valign="absbottom"> <A class=blacknavigation 
730            href="http://www.developerpipeline.com/contact.jhtml">Contact Us</A> 
731            <IMG height=11 hspace=5 
732            src="heaplayers-article-cuj_files/orangeline.gif" width=2 border=0 
733            valign="absbottom"> <A class=blacknavigation 
734            href="http://www.developerpipeline.com/about.jhtml">About Us</A> 
735            <IMG height=11 hspace=5 
736            src="heaplayers-article-cuj_files/orangeline.gif" width=2 border=0 
737            valign="absbottom"> <A class=blacknavigation 
738            href="http://www.cmp.com/delivery/privacy.html">Privacy</A> <IMG 
739            height=11 hspace=5 src="heaplayers-article-cuj_files/orangeline.gif" 
740            width=2 border=0 valign="absbottom"> <A class=blacknavigation 
741            href="http://www.cmp.com/delivery/privacy.html#california">Your
742            California Privacy Rights</A> </DIV></TD></TR>
743        <TR>
744          <TD align=middle bgColor=#999999><IMG height=1 hspace=0 
745            src="heaplayers-article-cuj_files/blank.gif" width=770 
746        border=0></TD></TR>
747        <TR>
748          <TD><!-- indusrty brains table -->
749            <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
750              <TBODY>
751              <TR>
752                <TD vAlign=center align=middle><BR><BR><!-- indusrty brains --><SPAN 
753                  id=nointelliTXT>
754                  <TABLE cellSpacing=2 cellPadding=0 width="90%" bgColor=#223378 
755                  border=0>
756                    <TBODY>
757                    <TR>
758                      <TD>
759                        <TABLE class=txtBlk_small cellSpacing=0 cellPadding=5 
760                        width="100%" bgColor=#efefef border=0>
761                          <TBODY>
762                          <TR>
763                            <TD>
764                              <DIV align=center><SPAN 
765                              class=txtBlk_small><B>MarketPlace</B></SPAN></DIV><BR>
766                              <DIV align=center><A 
767                              href="http://www.industrybrains.com/cmpsd">Wanna
768                              see your ad
769                    here?</A></DIV></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></SPAN><!-- end IB --></TD></TR></TBODY></TABLE><BR><!-- end indusrty brains table-->
770            <DIV class=BOTnav><A class=orange11 
771            href="http://www.internetweek.com/"></A>Developer Network Websites:
772            <A class=orange11 href="http://www.byte.com/" 
773            target=_blank>BYTE.com</A>, <A class=orange11 
774            href="http://www.cuj.com/" target=_blank>C/C++ Users Journal</A>, <A 
775            class=orange11 href="http://developerpipeline.com/" 
776            target=_blank>Developer Pipeline</A>, <A class=orange11 
777            href="http://www.ddj.com/" target=_blank>Dr. Dobb's Journal</A>, <A 
778            class=orange11 href="http://www.dotnetjunkies.com/" 
779            target=_blank>DotNetJunkies</A>, <A class=orange11 
780            href="http://msdn.microsoft.com/msdnmag/" target=_blank>MSDN
781            Magazine</A>, <A class=orange11 href="http://www.samag.com/" 
782            target=_blank>Sys Admin</A>, <A class=orange11 
783            href="http://www.sdexpo.com/" target=_blank>SD Expo</A>, <A 
784            class=orange11 href="http://www.sdmagazine.com/" 
785            target=_blank>Software Development Magazine</A>, <A class=orange11 
786            href="http://www.sqljunkies.com/" target=_blank>SqlJunkies</A>, <A 
787            class=orange11 href="http://www.unixreview.com/" 
788            target=_blank>Unixreview</A>, <A class=orange11 
789            href="http://www.windevnet.com/" target=_blank>Windows Developer
790            Network</A>, <A class=orange11 
791            href="http://www.newarchitectmag.com/" target=_blank>New
792            Architect</A> </DIV></TD></TR>
793        <TR>
794          <TD align=middle bgColor=#cccccc>
795            <DIV class=BOTnavgrey><SPAN class=grey9><A class=grey9 
796            href="http://www.cmp.com/delivery/copyright.html">Copyright</A> ©
797            2005<A class=grey9 href="http://www.cmp.com/">CMP Media LLC.</A> |
798            DEVELOPER PIPELINE All rights reserved. <A class=grey9 
799            href="http://www.cmp.com/delivery/privacy.html">Privacy Policy</A> |
800            <A href="http://www.cmp.com/delivery/privacy.html#california">Your
801            California Privacy Rights</A> | <A class=grey9 
802            href="http://www.cmp.com/delivery/terms.html">Terms of Service</A> 
803            </SPAN></DIV></TD></TR>
804        <TR>
805          <TD align=middle bgColor=#e7e7e7><IMG height=2 hspace=0 
806            src="heaplayers-article-cuj_files/blank.gif" width=770 
807        border=0></TD></TR></TBODY></TABLE><!-- END BOTTOM NAVIGATION --><!-- bottom ad -->
808      <DIV align=center><BR><BR><!-- AD: 'http://localhost:8085/html.ng/site=sdmg&affiliate=sdmgdeveloperpipeline&pagepos=bottom&catid=&site_section=9843&articleid=141768&target=cpp&country=&state=' --><!-- Sniffer Code for Flash version=60 -->
809      <SCRIPT language=JavaScript>
810<!--
811var swf_click = "http://as.cmpnet.com/event.ng/Type=click&FlightID=45538&AdID=80366&TargetID=4721&Segments=1411,3108,3448,4875,5818,5864&Targets=2625,2878,4666,4721&Values=34,46,51,63,77,83,90,100,140,204,442,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&RawValues=&Redirect=http://www.intel.com/software/";
812var dcswf_click = escape(swf_click);
813var ShockMode = 0;
814var plugin = (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]) ? navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin : 0;
815
816if (plugin && parseInt(plugin.description.substring(plugin.description.indexOf(".")-1)) >= 6) 
817{
818ShockMode = 1;
819}
820else if (navigator.userAgent && navigator.userAgent.indexOf("MSIE")>=0 
821&& (navigator.userAgent.indexOf("Windows 95")>=0 || navigator.userAgent.indexOf("Windows 98")>=0 || navigator.userAgent.indexOf("Windows NT")>=0)) {
822document.write('<SCRIPT LANGUAGE=VBScript\> \n');
823document.write('on error resume next \n');
824document.write('ShockMode = (IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash.6")))\n');
825document.write('<\/SCRIPT\> \n');
826}
827if ( ShockMode ) {
828document.write('<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"');
829document.write(' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"');
830document.write(' ID=flashad WIDTH=728 HEIGHT=90>');
831document.write(' <PARAM NAME=movie VALUE="http://i.cmpnet.com/ads/graphics/as5/cc/flash/banner_728x90c_1209.swf?clickTag='+dcswf_click+'"> '); 
832document.write(' <PARAM NAME=quality VALUE=high> ');
833document.write(' <PARAM NAME=wmode VALUE=opaque> ');
834document.write(' <EMBED SRC="http://i.cmpnet.com/ads/graphics/as5/cc/flash/banner_728x90c_1209.swf?clickTag='+dcswf_click+'" QUALITY=high WMODE=opaque '); 
835document.write(' NAME=flashad swLiveConnect=TRUE WIDTH=728 HEIGHT=90');
836document.write(' TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">');
837document.write('</EMBED>');
838document.write('</OBJECT>');
839} else if (!(navigator.appName && navigator.appName.indexOf("Netscape")>=0 && navigator.appVersion.indexOf("2.")>=0)){
840document.write('<A HREF="http://as.cmpnet.com/event.ng/Type=click&FlightID=45538&AdID=80366&TargetID=4721&Segments=1411,3108,3448,4875,5818,5864&Targets=2625,2878,4666,4721&Values=34,46,51,63,77,83,90,100,140,204,442,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&RawValues=&Redirect=http://www.intel.com/software/" target="_top"><IMG SRC="http://i.cmpnet.com/ads/graphics/as5/cc/banner_728x90c.gif" WIDTH=728 HEIGHT=90 BORDER=0></A>');
841}
842//-->
843</SCRIPT>
844      <NOEMBED><A 
845      href="http://as.cmpnet.com/event.ng/Type=click&amp;FlightID=45538&amp;AdID=80366&amp;TargetID=4721&amp;Segments=1411,3108,3448,4875,5818,5864&amp;Targets=2625,2878,4666,4721&amp;Values=34,46,51,63,77,83,90,100,140,204,442,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&amp;RawValues=&amp;Redirect=http://www.intel.com/software/" 
846      target=_top><IMG height=90 
847      src="heaplayers-article-cuj_files/banner_728x90c.gif" width=728 
848      border=0></A> </NOEMBED><NOSCRIPT><A 
849      href="http://as.cmpnet.com/event.ng/Type=click&amp;FlightID=45538&amp;AdID=80366&amp;TargetID=4721&amp;Segments=1411,3108,3448,4875,5818,5864&amp;Targets=2625,2878,4666,4721&amp;Values=34,46,51,63,77,83,90,100,140,204,442,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&amp;RawValues=&amp;Redirect=http://www.intel.com/software/" 
850      target=_top><IMG height=90 
851      src="heaplayers-article-cuj_files/banner_728x90c.gif" width=728 
852      border=0></A> </NOSCRIPT><IMG height=1 src="" width=1 border=0> </DIV><!-- end bottom ad --><BR><FONT size=-1>web2 </FONT></TD>
853    <TD vAlign=top align=right width=170><!-- right column -->
854      <TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
855        <TBODY>
856        <TR>
857          <TD><!-- streaming media -->
858            <DIV style="MARGIN-TOP: 170px">
859            <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
860              <TBODY>
861              <TR>
862                <TD>
863                  <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
864                    <TBODY>
865                    <TR>
866                      <TD bgColor=#cc6600>
867                        <TABLE cellSpacing=0 cellPadding=3 width="100%" 
868border=0>
869                          <TBODY>
870                          <TR>
871                            <TD><FONT color=#ffffff><STRONG>DevNet
872                              Podcasts</STRONG></FONT> 
873</TD></TR></TBODY></TABLE></TD></TR>
874                    <TR>
875                      <TD bgColor=#ffd673 height=2></TD></TR></TBODY></TABLE>
876                  <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
877                    <TBODY>
878                    <TR>
879                      <TD width=1 bgColor=#999999><IMG height=1 hspace=0 
880                        src="C:\home\emery\projects\heaplayers\doc\heaplayers-article-cuj_files\blank(2).gif" 
881                        width=1 border=0></TD>
882                      <TD bgColor=#ffffff>
883                        <TABLE cellSpacing=0 cellPadding=5 width="100%" 
884border=0>
885                          <TBODY>
886                          <TR>
887                            <TD>
888                              <P><STRONG>Introducing Dobbscast Audio
889                              Blogs</STRONG></P>
890                              <P align=left><A 
891                              href="http://syndication.sdmediagroup.com/feeds/public/cmp_podcast_ddj.xml">Get
892                              the Dobbscast feed<BR><IMG alt="" 
893                              src="heaplayers-article-cuj_files/rss_podcast.gif" 
894                              border=0></A></P></TD></TR></TBODY></TABLE></TD>
895                      <TD width=1 bgColor=#999999><IMG height=1 hspace=0 
896                        src="C:\home\emery\projects\heaplayers\doc\heaplayers-article-cuj_files\blank(2).gif" 
897                        width=1 border=0></TD></TR>
898                    <TR>
899                      <TD bgColor=#999999><IMG height=1 hspace=0 
900                        src="C:\home\emery\projects\heaplayers\doc\heaplayers-article-cuj_files\blank(2).gif" 
901                        width=1 border=0></TD>
902                      <TD bgColor=#999999><IMG height=1 hspace=0 
903                        src="C:\home\emery\projects\heaplayers\doc\heaplayers-article-cuj_files\blank(2).gif" 
904                        width=1 border=0></TD>
905                      <TD bgColor=#999999><IMG height=1 hspace=0 
906                        src="C:\home\emery\projects\heaplayers\doc\heaplayers-article-cuj_files\blank(2).gif" 
907                        width=1 
908            border=0></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></DIV><!-- end streaming media --><!-- skyscraper ad --><BR>
909            <DIV align=center><!-- AD: 'http://localhost:8085/html.ng/site=sdmg&affiliate=sdmgdeveloperpipeline&pagepos=sky&catid=&site_section=9843&articleid=141768&target=cpp&country=&state=' --><!-- Sniffer Code for Flash version=60 -->
910            <SCRIPT language=JavaScript>
911<!--
912var swf_click = "http://as.cmpnet.com/event.ng/Type=click&FlightID=45539&AdID=80365&TargetID=4720&Segments=1411,3108,3219,3448,4875,5820,5869&Targets=2625,2781,2878,4664,4720&Values=34,46,51,63,77,83,90,100,140,206,442,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&RawValues=&Redirect=http://www.intel.com/software/products/";
913var dcswf_click = escape(swf_click);
914var ShockMode = 0;
915var plugin = (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]) ? navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin : 0;
916
917if (plugin && parseInt(plugin.description.substring(plugin.description.indexOf(".")-1)) >= 6) 
918{
919ShockMode = 1;
920}
921else if (navigator.userAgent && navigator.userAgent.indexOf("MSIE")>=0 
922&& (navigator.userAgent.indexOf("Windows 95")>=0 || navigator.userAgent.indexOf("Windows 98")>=0 || navigator.userAgent.indexOf("Windows NT")>=0)) {
923document.write('<SCRIPT LANGUAGE=VBScript\> \n');
924document.write('on error resume next \n');
925document.write('ShockMode = (IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash.6")))\n');
926document.write('<\/SCRIPT\> \n');
927}
928if ( ShockMode ) {
929document.write('<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"');
930document.write(' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"');
931document.write(' ID=flashad WIDTH=125 HEIGHT=600>');
932document.write(' <PARAM NAME=movie VALUE="http://i.cmpnet.com/ads/graphics/as5/cc/flash/banner_125x600a_1209.swf?clickTag='+dcswf_click+'"> '); 
933document.write(' <PARAM NAME=quality VALUE=high> ');
934document.write(' <PARAM NAME=wmode VALUE=opaque> ');
935document.write(' <EMBED SRC="http://i.cmpnet.com/ads/graphics/as5/cc/flash/banner_125x600a_1209.swf?clickTag='+dcswf_click+'" QUALITY=high WMODE=opaque '); 
936document.write(' NAME=flashad swLiveConnect=TRUE WIDTH=125 HEIGHT=600');
937document.write(' TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">');
938document.write('</EMBED>');
939document.write('</OBJECT>');
940} else if (!(navigator.appName && navigator.appName.indexOf("Netscape")>=0 && navigator.appVersion.indexOf("2.")>=0)){
941document.write('<A HREF="http://as.cmpnet.com/event.ng/Type=click&FlightID=45539&AdID=80365&TargetID=4720&Segments=1411,3108,3219,3448,4875,5820,5869&Targets=2625,2781,2878,4664,4720&Values=34,46,51,63,77,83,90,100,140,206,442,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&RawValues=&Redirect=http://www.intel.com/software/products/" target="_top"><IMG SRC="http://i.cmpnet.com/ads/graphics/as5/cc/banner_125x600a.gif" WIDTH=125 HEIGHT=600 BORDER=0></A>');
942}
943//-->
944</SCRIPT>
945            <NOEMBED><A 
946            href="http://as.cmpnet.com/event.ng/Type=click&amp;FlightID=45539&amp;AdID=80365&amp;TargetID=4720&amp;Segments=1411,3108,3219,3448,4875,5820,5869&amp;Targets=2625,2781,2878,4664,4720&amp;Values=34,46,51,63,77,83,90,100,140,206,442,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&amp;RawValues=&amp;Redirect=http://www.intel.com/software/products/" 
947            target=_top><IMG height=600 
948            src="heaplayers-article-cuj_files/banner_125x600a.gif" width=125 
949            border=0></A> </NOEMBED><NOSCRIPT><A 
950            href="http://as.cmpnet.com/event.ng/Type=click&amp;FlightID=45539&amp;AdID=80365&amp;TargetID=4720&amp;Segments=1411,3108,3219,3448,4875,5820,5869&amp;Targets=2625,2781,2878,4664,4720&amp;Values=34,46,51,63,77,83,90,100,140,206,442,645,646,657,944,945,1184,1311,1405,1412,1426,1716,1736,1767,1785,1935,1936,1944,1970,2310,2327,2352,2759,2767,2862,2878,2942,3067,3080&amp;RawValues=&amp;Redirect=http://www.intel.com/software/products/" 
951            target=_top><IMG height=600 
952            src="heaplayers-article-cuj_files/banner_125x600a.gif" width=125 
953            border=0></A> </NOSCRIPT><IMG height=1 src="" width=1 border=0> 
954            </DIV><!-- end skyscraper --></TD></TR></TBODY></TABLE><!-- end right column --></TD></TR></TBODY></TABLE></DIV></BODY></HTML>
Note: See TracBrowser for help on using the repository browser.