views:

462

answers:

6

Hi, I'm storing some classes with WideString parameters describing them (like name, description and some others). Now if I change all those WideStrings to simple "string" (I'm using alias actually so I have to change one line only), memory usage is about 5% bigger!! than previously... How is that possible, since each char of the string is twice smaller than the WideChar?

thanks in advance!

m.

A: 

It's possible because those strings almost certainly constitute a (relatively) small part of the memory used to run your program. Other space is used by handles, various objects, etc.

For the sake of example, let's assume you have about 100KB of text when using ANSI strings and you convert it to Widestrings instead. Only those 100KB would be affected, but those 100KB don't constitute every single byte of your program's memory footprint. Space will be used for forms, handles, numbers, and other objects, but because they aren't being changed in the conversion, they obviously won't require more memory than before the conversion.

Michael Madsen
ok, but the *only* difference between unicode and non-unicode version is the string/widestring change. *nothing else*.The data is generated from same file and is exactly the same (as expected). The data consists in about 3/4 of strings.I've checked it on quite a big piece of data, the result took additional 45 Mb in memory (43 in case of using WideString), and it is fully reproducible.
migajek
A: 

WideStrings use a different memory manager (a windows one) then AnsiStrings (Delphi's) and are reference counted different. How did you measure the memory usage? With what tool and what exact counter?

Lars Truijens
A: 

How do you measure memoery used? IIRC WideString memory is allocated using SysAllocString() and thereby bypass the Delphi memory manager.

ldsandon
A: 

Memory manager in Delphi always take more memory, than it really needs. It is such speed improvement.

Torbins
A: 

Are you using AnsiString or ShortString type when not using the WideString? Is it possible that you are compiling with {$H–} compiler flag (either globally or in some unit) that treats all "String" types as ShortString? If your strings are of ShortString type and you do not specify the string size then the memory allocated is always 256 bytes.

DeanM
+3  A: 

The Delphi memory manager does not release all unused memory to the operating system. Fragmentation can also kick in very badly. Both depend on the actual memory manager you use (FastMM is usually better than the stock memory manager in D7, but any memory manager can be brought to it's knees by using a memory manager specific series of memory usage patterns). Furthermore, WideStrings, though they are COM strings, are not reference counted, and might not be released even later than the normal strings.

The only reliable way to query actual memory message in Delphi is to ask the memory manager your Delphi program uses. This function in the System unit does that for you:

function GetHeapStatus: THeapStatus

--jeroen

edit: 20100104 in reaction to comment by Marco: (FastMM is usually better than the stock memory manager in D7, but any memory manager can be brought to it's knees by using a memory manager specific series of memory usage patterns)

Jeroen Pluimers
+1 heap fragmentation or memory usage by procexplorer syndrome. FastMM is btw not _always_ better. In specially if the code has been previously tuned, the old one can be faster. So while Fastmm is better on the whole, the rule of benchmarking (measure!) still applies.
Marco van de Voort
Thanks, I edited the answer because of your comment.
Jeroen Pluimers