📄 malloc.html
字号:
<blockquote><table cellpadding="10" border="0"><tr><td valign="top"><b>N</b></td><td valign="top">The amount of raw memory needed by the memory allocation systemin order to guarantee that no memory allocation will ever fail.</td></tr><tr><td valign="top"><b>M</b></td><td valign="top">The maximum amount of memory that the application ever has checked outat any point in time.</td></tr><tr><td valign="top"><b>n</b></td><td valign="top">The ratio of the largest memory allocation to the smallest. We assumethat every memory allocation size is an integer multiple of the smallest memoryallocation size.</td></tr></table></blockquote><p>Robson proves the following result:</p><blockquote><b>N</b> = <b>M</b>*(1 + (log<sub>2</sub> <b>n</b>)/2) - <b>n</b> + 1</blockquote><p>Colloquially, the Robson proof shows that in order to guaranteebreakdown-free operation, any memory allocator must use a memory poolof size <b>N</b> which exceeds the maximum amount of memory everyused <b>M</b> by a multiplier that depends on <b>n</b>, the ratio of the largest to the smallest allocation size. In otherwords, unless all memory allocations are of exactly the same size(<b>n</b>=1) then the system needs access to more memory than it willever use at one time. Furthermore, we see that the amount of surplusmemory required grows rapidly as the ratio of largest to smallestallocations increases, and so there is strong incentive to keep allallocations as near to the same size as possible.</p><p>Robson's proof is constructive. He provides an algorithm for computing a sequence of allocationand deallocation operations that will lead to an allocation failure due tomemory fragmentation if available memory is as much as one byteless than <b>N</b>.And, Robson shows that a power-of-two first-fit memory allocator(such as implemented by <a href="malloc.html#memsys5">memsys5</a>) will never fail a memory allocationprovided that available memory is <b>N</b> or more bytes.</p><p>The values <b>M</b> and <b>n</b> are properties of the application.If an application is constructed in such a way that both <b>M</b> and<b>n</b> are known, or at least have known upper bounds, and if theapplication usesthe <a href="malloc.html#memsys5">memsys5</a> memory allocator and is provided with <b>N</b> bytes ofavailable memory space using <a href="c3ref/c_config_getmalloc.html">SQLITE_CONFIG_HEAP</a>then Robson proves that no memory allocation request will ever failwithin the application.To put this another way, the application developer can select a valuefor <b>N</b> that will guarantee that no call to any SQLite interfacewill ever return <a href="c3ref/c_abort.html">SQLITE_NOMEM</a>. The memory pool will never becomeso fragmented that a new memory allocation request cannot be satisfied.This is an important property forapplications where a software fault could cause injury, physical harm, orloss of irreplaceable data.</p><h3>4.1 Computing and controlling parameters <b>M</b> and <b>n</b></h3><p>The Robson proof applies separately to each of the memory allocatorsused by SQLite:</p><ul><li>The general-purpose memory allocator (<a href="malloc.html#memsys5">memsys5</a>).</li><li>The <a href="malloc.html#scratch">scratch memory allocator</a>.</li><li>The <a href="malloc.html#pagecache">pagecache memory allocator</a>.</li><li>The <a href="malloc.html#lookaside">lookaside memory allocator</a>.</li></ul><p>For allocators other than <a href="malloc.html#memsys5">memsys5</a>,all memory allocations are of the same size. Hence, <b>n</b>=1and therefore <b>N</b>=<b>M</b>. In other words, the memory pool needbe no larger than the largest amount of memory in use at any given moment.</p><p>SQLite guarantees that no thread will ever use more than a singlescratch memory slot at one time. So if an application allocates as manyscratch memory slots as there are threads, and assuming the size ofeach slot is large enough, there is never a chance of overflowing thescratch memory allocator. An upper bound on the size of scratch memoryallocations is six times the largest page size. It is easy, therefore,to guarantee breakdown-free operation of the scratch memory allocator.</p><p>The usage of pagecache memory is somewhat harder to control inSQLite version 3.6.1, though mechanisms are planned for subsequentreleases that will make controlling pagecache memory much easier.Prior to the introduction of these new mechanisms, the only wayto control pagecache memory is using the <a href="pragma.html#pragma_cache_size">cache_size pragma</a>.</p><p>Safety-critical applications will usually want to modify thedefault lookaside memory configuration so that when the initiallookaside memory buffer is allocated during <a href="c3ref/open.html">sqlite3_open()</a> theresulting memory allocation is not so large as to force the <b>n</b>parameter to be too large. In order to keep <b>n</b> under control,it is best to try to keep the largest memory allocation below 2 or 4kilobytes. Hence, a reasonable default setup for the lookasidememory allocator might any one of the following:</p><blockquote><pre>sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 32, 32); /* 1K */sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 64, 32); /* 2K */sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 32, 64); /* 2K */sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 64, 64); /* 4K */</pre></blockquote><p>Another approach is to initially disable the lookaside memoryallocator:</p><blockquote><pre>sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);</pre></blockquote><p>Then let the application maintain a separate pool of largerlookaside memory buffers that it can distribute to <a href="c3ref/sqlite3.html">database connections</a>as they are created. In the common case, the application will onlyhave a single <a href="c3ref/sqlite3.html">database connection</a> and so the lookaside memory poolcan consist of a single large buffer.</p><blockquote><pre>sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, aStatic, 256, 500);</pre></blockquote><p>The lookaside memory allocator is really intended as performanceoptimization, not as a method for assuring breakdown-free memory allocation,so it is not unreasonable to completely disable the lookaside memoryallocator for safety-critical operations.</p><p>The general purpose memory allocator is the most difficult memory poolto manage because it supports allocations of varying sizes. Since <b>n</b> is a multiplier on <b>M</b> we want to keep <b>n</b> as smallas possible. This argues for keeping the minimum allocation size for<a href="malloc.html#memsys5">memsys5</a> as large as possible. In most applications, the<a href="malloc.html#lookaside">lookaside memory allocator</a> is able to handle small allocations. Soit is reasonable to set the minimum allocation size for <a href="malloc.html#memsys5">memsys5</a> to2, 4 or even 8 times the maximum size of a lookaside allocation. A minimum allocation size of 512 is a reasonable setting.</p><p>Further to keeping <b>n</b> small, one desires to keep the size ofthe largest memory allocations under control.Large requests to the general-purpose memory allocatormight come from several sources:</p><ol><li>SQL table rows that contain large strings or BLOBs.</li><li>Complex SQL queries that compile down to large <a href="c3ref/stmt.html">prepared statements</a>.</li><li>SQL parser objects used internally by <a href="c3ref/prepare.html">sqlite3_prepare_v2()</a>.</li><li>Storage space for <a href="c3ref/sqlite3.html">database connection</a> objects.</li><li>Scratch memory allocations that overflow into the general-purpose memory allocator.</li><li>Page cache memory allocations that overflow into the general-purpose memory allocator.</li><li>Lookaside buffer allocations for new <a href="c3ref/sqlite3.html">database connections</a>.</li></ol><p>The last three allocations can be controlled and/or eliminated byconfiguring the <a href="malloc.html#scratch">scratch memory allocator</a>, <a href="malloc.html#pagecache">pagecache memory allocator</a>,and <a href="malloc.html#lookaside">lookaside memory allocator</a> appropriately, as described above.The storage space required for <a href="c3ref/sqlite3.html">database connection</a> objects dependsto some extent on the length of the filename of the database file, butrarely exceeds 2KB on 32-bit systems. (More space is required on64-bit systems due to the increased size of pointers.)Each parser object uses about 1.6KB of memory. Thus, elements 3 through 7above can easily be controlled to keep the maximum memory allocationsize below 2KB.</p><p>If the application is designed to manage data in small pieces,then the database should never contain any large strings or BLOBsand hence element 1 above should not be a factor. If the databasedoes contain large strings or BLOBs, they should be read using<a href="c3ref/blob.html">incremental BLOB I/O</a> and rows that contain thelarge strings or BLOBs should never be update by any means otherthan <a href="c3ref/blob.html">incremental BLOB I/O</a>. Otherwise, the <a href="c3ref/step.html">sqlite3_step()</a> routine will need to read the entire row intocontiguous memory at some point, and that will involve at leastone large memory allocation.</p><p>The final source of large memory allocations is the space to holdthe <a href="c3ref/stmt.html">prepared statements</a> that result from compiling complex SQLoperations. Ongoing work by the SQLite developers is reducing theamount of space required here. But large and complex queries mightstill require <a href="c3ref/stmt.html">prepared statements</a> that are several kilobytes insize. The only workaround at the moment is for the application tobreak complex SQL operations up into two or more smaller and simpler operations contained in separate <a href="c3ref/stmt.html">prepared statements</a>.</p><p>All things considered, applications should normally be able tohold their maximum memory allocation size below 2K or 4K. Thisgives a value for log<sub>2</sub>(<b>n</b>) of 2 or 3. This willlimit <b>N</b> to between 2 and 2.5 times <b>M</b>.</p><p>The maximum amount of general-purpose memory needed by the applicationis determined by such factors as how many simultaneous open <a href="c3ref/sqlite3.html">database connection</a> and <a href="c3ref/stmt.html">prepared statement</a> objects the applicationuses, and on the complexity of the <a href="c3ref/stmt.html">prepared statements</a>. For anygiven application, these factors are normally fixed and can bedetermined experimentally using <a href="c3ref/c_status_malloc_size.html">SQLITE_STATUS_MEMORY_USED</a>.A typical application might only use about 40KB of general-purposememory. This gives a value of <b>N</b> of around 100KB.</p><h3>4.2 Ductile failure</h3><p>If the memory allocation subsystems within SQLite are configuredfor breakdown-free operation but the actual memory usage exceedsdesign limits set by the <a href="malloc.html#nofrag">Robson proof</a>, SQLite will usually continue to operate normally.The <a href="malloc.html#scratch">scratch memory allocator</a>, the <a href="malloc.html#pagecache">pagecache memory allocator</a>,and the <a href="malloc.html#lookaside">lookaside memory allocator</a> all automatically failoverto the <a href="malloc.html#memsys5">memsys5</a> general-purpose memory allocator. And it is usually thecase that the <a href="malloc.html#memsys5">memsys5</a> memory allocator will continue to functionwithout fragmentation even if <b>M</b> and/or <b>n</b> exceeds the limitsimposed by the <a href="malloc.html#nofrag">Robson proof</a>. The <a href="malloc.html#nofrag">Robson proof</a> shows that it is possible for a memory allocation to break down and fail in this circumstance, but such a failure requires an especiallydespicable sequence of allocations and deallocations - a sequence thatSQLite has never been observed to follow. So in practice it is usuallythe case that the limits imposed by Robson can be exceeded by aconsiderable margin with no ill effect.</p><p>Nevertheless, application developers are admonished to monitorthe state of the memory allocation subsystems and raise alarms whenmemory usage approaches or exceeds Robson limits. In this way,the application will provide operators with abundant warning wellin advance of failure.The <a href="malloc.html#memstatus">memory statistics</a> interfaces of SQLite provide the application withall the mechanism necessary to complete the monitoring portion ofthis task.</p><a name="stability"></a><h2>5.0 Stability Of Memory Interfaces</h2><p>As of this writing (circa SQLite version 3.6.1) all of the alternativememory allocators and mechanisms for manipulating, controlling, andmeasuring memory allocation in SQLite are considered experimental andsubject to change from one release to the next. These interfaces arein the process of being refined to work on a wide variety of systemsunder a range of constraints. The SQLite developers need the flexibilityto change the memory allocator interfaces in order to best meet theneeds of a wide variety of systems.</p><p>One may anticipate that the memory allocator interfaces willeventually stabilize. Appropriate notice will be given when thatoccurs. In the meantime, applications developers who make use ofthese interfaces need to be prepared to modify their applicationsto accommodate changes in the SQLite interface.</p><a name="summary"></a><h2>6.0 Summary Of Memory Allocator Interfaces</h2><p><i>To be completed...</i></p><hr><small><i>This page last modified 2008/11/12 14:22:39 UTC</i></small></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -