📄 fastmm4.pas
字号:
(*
Fast Memory Manager 4.26
Description:
A fast replacement memory manager for Borland Delphi Win32 applications that
scales well under multi-threaded usage, is not prone to memory fragmentation,
and supports shared memory without the use of external .DLL files.
Homepage:
http://fastmm.sourceforge.net
Advantages:
- Fast
- Low overhead. FastMM is designed for an average of 5% and maximum of 10%
overhead per block.
- Supports up to 3GB of user mode address space under Windows 32-bit and 4GB
under Windows 64-bit. Add the "$SetPEFlags $20" option (in curly braces)
to your .dpr to enable this.
- Highly aligned memory blocks. Can be configured for either 8-byte or 16-byte
alignment.
- Good scaling under multi-threaded applications
- Intelligent reallocations. Avoids slow memory move operations through
not performing unneccesary downsizes and by having a minimum percentage
block size growth factor when an in-place block upsize is not possible.
- Resistant to address space fragmentation
- No external DLL required when sharing memory between the application and
external libraries (provided both use this memory manager)
- Optionally reports memory leaks on program shutdown. (This check can be set
to be performed only if Delphi is currently running on the machine, so end
users won't be bothered by the error message.)
- Supports Delphi 5 (or later), C++ Builder 6 (or later), Kylix 3.
Usage:
Delphi:
Place this unit as the very first unit under the "uses" section in your
project's .dpr file. When sharing memory between an application and a DLL
(e.g. when passing a long string or dynamic array to a DLL function), both the
main application and the DLL must be compiled using this memory manager with
the required conditional defines set. The are some conditional defines
(inside FastMM4Options.inc) which may be used to tweak the memory manager. To
enable support for a user mode address space greater than 2GB you will have to
use the EditBin* tool to set the LARGE_ADDRESS_AWARE flag in the EXE header.
This informs Windows x64 or Windows 32-bit (with the /3GB option set) that the
application supports an address space larger than 2GB (up to 4GB). In Delphi 7
and later you can also specify this flag through the compiler directive
{$SetPEFlags $20}
*The EditBin tool ships with the MS Visual C compiler.
C++ Builder 6:
Refer to the instructions inside FastMM4BCB.cpp.
License:
This work is copyright Professional Software Development / Pierre le Riche. It
is released under the Mozilla Public Licence 1.1 (MPL 1.1). The licence terms
are described on this page: http://www.mozilla.org/MPL/MPL-1.1.html. If you
find FastMM useful or you would like to support further development, a donation
would be much appreciated. My banking details are:
Country: South Africa
Bank: ABSA Bank Ltd
Branch: Somerset West
Branch Code: 334-712
Account Name: PSD (Distribution)
Account No.: 4041827693
Swift Code: ABSAZAJJ
My PayPal account is:
bof@psd.co.za
Contact Details:
Below are my contact details if you would like to get in touch with me. If you
use this memory manager I would like to hear from you: please e-mail me your
comments - good and bad.
Snailmail:
PO Box 2514
Somerset West
7129
South Africa
E-mail:
plr@psd.co.za
Support:
If you have trouble using FastMM, you are welcome to drop me an e-mail at the
address above, or you may post your questions in the BASM newsgroup on the
Borland news server (which is where I hang out quite frequently).
Disclaimer:
FastMM has been tested extensively with both single and muiltithreaded
applications on various hardware platforms, but unfortunately I am not in a
position to make any guarantees. Use it at your own risk.
Acknowledgements (for version 4):
- Eric Grange for his RecyclerMM on which the earlier versions of FastMM were
based. RecyclerMM was what inspired me to try and write my own memory
manager back in early 2004.
- Dennis Christensen for his tireless efforts with the Fastcode project:
helping to develop, optimize and debug the growing Fastcode library.
- Pierre Y. for his suggestions regarding the extension of the memory leak
checking options.
- Anders Isaksson and Greg for finding and identifying the "DelphiIsRunning"
bug under Delphi 5.
- Francois Malan for finding the bug that caused compilation to fail when
both the "AssumeMultiThreaded" and "CheckHeapForCorruption" options were set.
- Craig Peterson for helping me identify the cache associativity issues that
could arise due to medium blocks always being an exact multiple of 256 bytes.
Also for various other bug reports and enhancement suggestions.
- Jarek Karciarz, Vladimir Ulchenko (Vavan) and Bob Gonder for their help in
implementing the BCB support.
- Ben Taylor for his suggestion to display the object class of all memory
leaks.
- Jean Marc Eber and Vincent Mahon (the Memcheck guys) for the call stack
trace code and also the method used to catch virtual method calls on freed
objects.
- Nahan Hyn for the suggestion to be able to enable or disable memory leak
reporting through a global variable (the "ManualLeakReportingControl"
option.)
- Leonel Togniolli for various suggestions with regard to enhancing the bug
tracking features of FastMM and other helpful advice.
- Joe Bain and Leonel Togniolli for the workaround to QC#10922 affecting
compilation under Delphi 2005.
- Robert Marquardt for the suggestion to make localisation of FastMM easier by
having all string constants together.
- Simon Kissel and Fikret Hasovic for their help in implementing Kylix support.
- Matthias Thoma, Petr Vones, Robert Rossmair and the rest of the JCL crew for
their debug info library used in the debug info support DLL.
- Andreas Hausladen for the suggestion to use an external DLL to enable the
reporting of debug information.
- Alexander Tabakov for various good suggestions regarding the debugging
facilities of FastMM.
- M. Skloff for some useful suggestions and bringing to my attention some
compiler warnings.
- Martin Aignesberger for the code to use madExcept instead of the JCL library
inside the debug info support DLL.
- Diederik and Dennis Passmore for the suggestion to be able to register
expected leaks.
- Dario Tiraboschi and Mark Gebauer for pointing out the problems that occur
when range checking and complete boolean evaluation is turned on.
- Hanspeter Widmer for his suggestion to have an option to display install and
uninstall debug messages and moving options to a separate file.
- Arthur Hoornweg for notifying me of the image base being incorrect for
borlndmm.dll.
- Theo Carr-Brion and Hanspeter Widmer for finding the false alarm error
message "Block Header Has Been Corrupted" bug in FullDebugMode.
- Danny Heijl for reporting the compiler error in "release" mode.
- Omar Zelaya for reporting the BCB support regression bug.
- Dan Miser for his suggestions regarding the stack trace and messagebox
functionality.
- Arjen de Ruijter for fixing the bug in CheckExpectedLeak that caused it
to not properly detect expected leaks registered by class when in
"FullDebugMode".
- Aleksander Oven for reporting the installation problem when trying to use
FastMM in an application together with libraries that all use runtime
packages.
- Any other Fastcoders or supporters that I have forgotten, and also everyone
that helped with the older versions.
Change log:
Version 1.00 (28 June 2004):
- First version (called PSDMemoryManager). Based on RecyclerMM (free block
stack approach) by Eric Grange.
Version 2.00 (3 November 2004):
- Complete redesign and rewrite from scratch. Name changed to FastMM to
reflect this fact. Uses a linked-list approach. Is faster, has less memory
overhead, and will now catch most bad pointers on FreeMem calls.
Version 3.00 (1 March 2005):
- Another rewrite. Reduced the memory overhead by: (a) not having a separate
memory area for the linked list of free blocks (uses space inside free
blocks themselves) (b) batch managers are allocated as part of chunks (c)
block size lookup table size reduced. This should make FastMM more CPU
cache friendly.
Version 4.00 (7 June 2005):
- Yet another rewrite. FastMM4 is in fact three memory managers in one: Small
blocks (up to a few KB) are managed through the binning model in the same
way as previous versions, medium blocks (from a few KB up to approximately
256K) are allocated in a linked-list fashion, and large blocks are grabbed
directly from the system through VirtualAlloc. This 3-layered design allows
very fast operation with the most frequently used block sizes (small
blocks), while also minimizing fragmentation and imparting significant
overhead savings with blocks larger than a few KB.
Version 4.01 (8 June 2005):
- Added the options "RequireDebugInfoForLeakReporting" and
"RequireIDEPresenceForLeakReporting" as suggested by Pierre Y.
- Fixed the "DelphiIsRunning" function not working under Delphi 5, and
consequently no leak checking. (Reported by Anders Isaksson and Greg.)
Version 4.02 (8 June 2005):
- Fixed the compilation error when both the "AssumeMultiThreaded" and
"CheckHeapForCorruption options were set. (Reported by Francois Malan.)
Version 4.03 (9 June 2005):
- Added descriptive error messages when FastMM4 cannot be installed because
another MM has already been installed or memory has already been allocated.
Version 4.04 (13 June 2005):
- Added a small fixed offset to the size of medium blocks (previously always
exact multiples of 256 bytes). This makes performance problems due to CPU
cache associativity limitations much less likely. (Reported by Craig
Peterson.)
Version 4.05 (17 June 2005):
- Added the Align16Bytes option. Disable this option to drop the 16 byte
alignment restriction and reduce alignment to 8 bytes for the smallest
block sizes. Disabling Align16Bytes should lower memory consumption at the
cost of complicating the use of aligned SSE move instructions. (Suggested
by Craig Peterson.)
- Added a support unit for C++ Builder 6 - Add FastMM4BCB.cpp and
FastMM4.pas to your BCB project to use FastMM instead of the RTL MM. Memory
leak checking is not supported because (unfortunately) once an MM is
installed under BCB you cannot uninstall it... at least not without
modifying the RTL code in exit.c or patching the RTL code runtime. (Thanks
to Jarek Karciarz, Vladimir Ulchenko and Bob Gonder.)
Version 4.06 (22 June 2005):
- Displays the class of all leaked objects on the memory leak report and also
tries to identify leaked long strings. Previously it only displayed the
sizes of all leaked blocks. (Suggested by Ben Taylor.)
- Added support for displaying the sizes of medium and large block memory
leaks. Previously it only displayed details for small block leaks.
Version 4.07 (22 June 2005):
- Fixed the detection of the class of leaked objects not working under
Windows 98/Me.
Version 4.08 (27 June 2005):
- Added a BorlndMM.dpr project to allow you to build a borlndmm.dll that uses
FastMM4 instead of the default memory manager. You may replace the old
DLL in the Delphi \Bin directory to make the IDE use this memory manager
instead.
Version 4.09 (30 June 2005):
- Included a patch fix for the bug affecting replacement borlndmm.dll files
with Delphi 2005 (QC#14007). Compile the patch, close Delphi, and run it
once to patch your vclide90.bpl. You will now be able to use the
replacement borlndmm.dll to speed up the Delphi 2005 IDE as well.
Version 4.10 (7 July 2005):
- Due to QC#14070 ("Delphi IDE attempts to free memory after the shutdown
code of borlndmm.dll has been called"), FastMM cannot be uninstalled
safely when used inside a replacement borlndmm.dll for the IDE. Added a
conditional define "NeverUninstall" for this purpose.
- Added the "FullDebugMode" option to pad all blocks with a header and footer
to help you catch memory overwrite bugs in your applications. All blocks
returned to freemem are also zeroed out to help catch bugs involving the
use of previously freed blocks. Also catches attempts at calling virtual
methods of freed objects provided the block in question has not been reused
since the object was freed. Displays stack traces on error to aid debugging.
- Added the "LogErrorsToFile" option to log all errors to a text file in the
same folder as the application.
- Added the "ManualLeakReportingControl" option (suggested by Nahan Hyn) to
enable control over whether the memory leak report should be done or not
via a global variable.
Version 4.11 (7 July 2005):
- Fixed a compilation error under Delphi 2005 due to QC#10922. (Thanks to Joe
Bain and Leonel Togniolli.)
- Fixed leaked object classes not displaying in the leak report in
"FullDebugMode".
Version 4.12 (8 July 2005):
- Moved all the string constants to one place to make it easier to do
translations into other languages. (Thanks to Robert Marquardt.)
- Added support for Kylix. Some functionality is currently missing: No
support for detecting the object class on leaks and also no MM sharing.
(Thanks to Simon Kissel and Fikret Hasovic).
Version 4.13 (11 July 2005):
- Added the FastMM_DebugInfo.dll support library to display debug info for
stack traces.
- Stack traces for the memory leak report is now logged to the log file in
"FullDebugMode".
Version 4.14 (14 July 2005):
- Fixed string leaks not being detected as such in "FullDebugMode". (Thanks
to Leonel Togniolli.)
- Fixed the compilation error in "FullDebugMode" when "LogErrorsToFile" is
not set. (Thanks to Leonel Togniolli.)
- Added a "Release" option to allow the grouping of various options and to
make it easier to make debug and release builds. (Thanks to Alexander
Tabakov.)
- Added a "HideMemoryLeakHintMessage" option to not display the hint below
the memory leak message. (Thanks to Alexander Tabakov.)
- Changed the fill character for "FullDebugMode" from zero to $80 to be able
to differentiate between invalid memory accesses using nil pointers to
invalid memory accesses using fields of freed objects. FastMM tries to
reserve the 64K block starting at $80800000 at startup to ensure that an
A/V will occur when this block is accessed. (Thanks to Alexander Tabakov.)
- Fixed some compiler warnings. (Thanks to M. Skloff)
- Fixed some display bugs in the memory leak report. (Thanks to Leonel
Togniolli.)
- Added a "LogMemoryLeakDetailToFile" option. Some applications leak a lot of
memory and can make the log file grow very large very quickly.
- Added the option to use madExcept instead of the JCL Debug library in the
debug info support DLL. (Thanks to Martin Aignesberger.)
- Added procedures "GetMemoryManagerState" and "GetMemoryMap" to retrieve
statistics about the current state of the memory manager and memory pool.
(A usage tracker form together with a demo is also available.)
Version 4.15 (14 July 2005):
- Fixed a false 4GB(!) memory leak reported in some instances.
Version 4.16 (15 July 2005):
- Added the "CatchUseOfFreedInterfaces" option to catch the use of interfaces
of freed objects. This option is not compatible with checking that a freed
block has not been modified, so enable this option only when hunting an
invalid interface reference. (Only relevant if "FullDebugMode" is set.)
- During shutdown FastMM now checks that all free blocks have not been
modified since being freed. (Only when "FullDebugMode" is set and
"CatchUseOfFreedInterfaces" is disabled.)
Version 4.17 (15 July 2005):
- Added the AddExpectedMemoryLeaks and RemoveExpectedMemoryLeaks procedures to
register/unregister expected leaks, thus preventing the leak report from
displaying if only expected leaks occurred. (Thanks to Diederik and Dennis
Passmore for the suggestion.)
- Fixed the "LogMemoryLeakDetailToFile" not logging memory leak detail to file
as it is supposed to. (Thanks to Leonel Togniolli.)
Version 4.18 (18 July 2005):
- Fixed some issues when range checking or complete boolean evaluation is
switched on. (Thanks to Dario Tiraboschi and Mark Gebauer.)
- Added the "OutputInstallUninstallDebugString" option to display a message when
FastMM is installed or uninstalled. (Thanks to Hanspeter Widmer.)
- Moved the options to a separate include file. (Thanks to Hanspeter Widmer.)
- Moved message strings to a separate file for easy translation.
Version 4.19 (19 July 2005):
- Fixed Kylix support that was broken in 4.14.
Version 4.20 (20 July 2005):
- Fixed a false memory overwrite report at shutdown in "FullDebugMode". If you
consistently got a "Block Header Has Been Corrupted" error message during
shutdown at address $xxxx0070 then it was probably a false alarm. (Thanks to
Theo Carr-Brion and Hanspeter Widmer.}
Version 4.21 (27 July 2005):
- Minor change to the block header flags to make it possible to immediately
tell whether a medium block is being used as a small block pool or not.
(Simplifies the leak checking and status reporting code.)
- Expanded the functionality around the management of expected memory leaks.
- Added the "ClearLogFileOnStartup" option. Deletes the log file during
initialization. (Thanks to M. Skloff.)
- Changed "OutputInstallUninstallDebugString" to use OutputDebugString instead
of MessageBox. (Thanks to Hanspeter Widmer.)
Version 4.22 (1 August 2005):
- Added a FastAllocMem function that avoids an unnecessary FillChar call with
large blocks.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -