Index: src/mem2.c ================================================================== --- src/mem2.c +++ src/mem2.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains the C functions that implement a memory ** allocation subsystem for use by SQLite. ** -** $Id: mem2.c,v 1.14 2007/10/03 08:46:45 danielk1977 Exp $ +** $Id: mem2.c,v 1.15 2007/10/15 19:34:32 drh Exp $ */ /* ** This version of the memory allocator is used only if the ** SQLITE_MEMDEBUG macro is defined and SQLITE_OMIT_MEMORY_ALLOCATION @@ -82,10 +82,15 @@ ** Guard words */ #define FOREGUARD 0x80F5E153 #define REARGUARD 0xE4676B53 +/* +** Number of malloc size increments to track. +*/ +#define NCSIZE 500 + /* ** All of the static variables used by this module are collected ** into a single structure named "mem". This is to keep the ** static variables organized and to reduce namespace pollution ** when this module is combined with other in the amalgamation. @@ -146,12 +151,19 @@ /* ** sqlite3MallocDisallow() increments the following counter. ** sqlite3MallocAllow() decrements it. */ int disallow; /* Do not allow memory allocation */ - - + + /* + ** Gather statistics on the sizes of memory allocations. + ** sizeCnt[i] is the number of allocation attempts of i*4 + ** bytes. i==NCSIZE is the number of allocation attempts for + ** sizes more than NCSIZE*4 bytes. + */ + int sizeCnt[NCSIZE]; + } mem; /* ** Enter the mutex mem.mutex. Allocate it if it is not already allocated. @@ -270,10 +282,15 @@ assert( mem.disallow==0 ); if( mem.alarmCallback!=0 && mem.nowUsed+nByte>=mem.alarmThreshold ){ sqlite3MemsysAlarm(nByte); } nByte = (nByte+3)&~3; + if( nByte/8>NCSIZE-1 ){ + mem.sizeCnt[NCSIZE-1]++; + }else{ + mem.sizeCnt[nByte/8]++; + } totalSize = nByte + sizeof(*pHdr) + sizeof(int) + mem.nBacktrace*sizeof(void*) + mem.nTitle; if( mem.iFail>0 ){ if( mem.iFail==1 ){ p = 0; @@ -438,10 +455,11 @@ */ void sqlite3_memdebug_dump(const char *zFilename){ FILE *out; struct MemBlockHdr *pHdr; void **pBt; + int i; out = fopen(zFilename, "w"); if( out==0 ){ fprintf(stderr, "** Unable to output memory debug output log: %s **\n", zFilename); return; @@ -457,10 +475,19 @@ pBt -= pHdr->nBacktraceSlots; backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out)); fprintf(out, "\n"); } } + fprintf(out, "COUNTS:\n"); + for(i=0; i%3d: %d\n", NCSIZE*8, mem.sizeCnt[NCSIZE-1]); + } fclose(out); } /* ** This routine is used to simulate malloc failures. Index: test/tester.tcl ================================================================== --- test/tester.tcl +++ test/tester.tcl @@ -9,11 +9,11 @@ # #*********************************************************************** # This file implements some common TCL routines used for regression # testing the SQLite library # -# $Id: tester.tcl,v 1.91 2007/09/01 09:02:54 danielk1977 Exp $ +# $Id: tester.tcl,v 1.92 2007/10/15 19:34:32 drh Exp $ set tcl_precision 15 set sqlite_pending_byte 0x0010000 @@ -201,10 +201,13 @@ puts "Writing unfreed memory log to \"./memleak.txt\"" sqlite3_memdebug_dump ./memleak.txt } } else { puts "All memory allocations freed - no leaks" + ifcapable memdebug { + sqlite3_memdebug_dump ./memusage.txt + } } puts "Maximum memory usage: [sqlite3_memory_highwater] bytes" foreach f [glob -nocomplain test.db-*-journal] { file delete -force $f }