... How to find it? ![]()
suppose;
string[] arr = new string[1000];
for(int i = 0; i < 1000; i++)
{
arr[i] = i.ToString();
}
So what will be the size allocated to arr variable in the memory (in kilobytes)? Is there any way to determine this?
(like... getting the size of the file (any) from the harddisk via code, in the same way getting the size of the variable in kilobytes)
(if, in genereal, a pc has 64MB-RAM (small) and in that arr is some 200KB in size)
-
-
arr consists of 1000 pointers to string objects, so the size of arr would be 1000 * 4 ( bytes) on a 32 bit system, and 1000 * 8 ( bytes ) on a 64 bit system.
It doesn't matter what you set each string to, because the strings are NOT stored within the array arr. The strings are stored within the separate string objects that are pointed to by arr. -
int size = System.Runtime.InteropServices.
Marshal.SizeOf(arr);
works for any object arr; -
evildictaitor wrote:
int size = System.Runtime.InteropServices.
Marshal.SizeOf(arr);
works for any object arr;
Yes and no. .NET plays games with memory usage, so you won't, really, be able to tell how much memory is being used.
If you are doing this for fun, then Marshal.SizeOf will work, but if, for example, that was an array of strings, you'd only get the size of the array, not the strings.
Plus, if you attempted to add in the size of the strings, you'd have to try to account for the fact that .NET reuses strings:
string s = "Bob";
string t = "Bob";
There is only 1 copy of "Bob" in memory.
-
Well, you can always iterate over each element, use StringCbLength (I believe that is the Win32 function you'd use in a native app) and that tells you the size of each string. Of course, StringCchLength tells you the size in characters, so you'd have to mult by sizeof(TCHAR) (remember, unicode!). Adding in the pointer overhead as tropo said should be a trivial, a mult and an add.
.NET is a going to be a bit different of course. You can count the characters like above, and that should be somewhat close to the value. -
DoomBringer wrote:Well, you can always iterate over each element, use StringCbLength (I believe that is the Win32 function you'd use in a native app) and that tells you the size of each string. Of course, StringCchLength tells you the size in characters, so you'd have to mult by sizeof(TCHAR) (remember, unicode!). Adding in the pointer overhead as tropo said should be a trivial, a mult and an add.
.NET is a going to be a bit different of course. You can count the characters like above, and that should be somewhat close to the value.
Or not even close, if there's any kind of overlap in the contents of the strings... if you were using straight C or C++ to do this, this way would get very close (because a string's just an array in C), but in VB or C#, you won't be able to guarantee that you're anywhere near the correct size.
-
now i am more confused...
:scratching-head: -
Raghavendra_Mudugal wrote:now i am more confused...
:scratching-head:
It all depends on why you want to know.
If you need to know, exactly, how much memory is being used by an object/application, you'll need to find a memory profiler that knows how .NET memory is arranged.
If you just want a general estimate, then do the math yourself:
int iLength = 0;
foreach(string s in stringarray)
iLength += s.Length;
iLength += (stringarray.Count * 4);
I'm guessing on the number 4, but I believe that it takes 4 bytes to store the reference to the string. If I'm wrong, then change it.
-
Memory is hard to calculate under .NET - as said before .NET reuses stuff and you don't get the size of the strings in this case, because the array really only consists of an array of pointers (references).
Why do you exactly need it? -
ScanIAm wrote:
...
Plus, if you attempted to add in the size of the strings, you'd have to try to account for the fact that .NET reuses strings:
string s = "Bob";
string t = "Bob";
There is only 1 copy of "Bob" in memory.
This is due to compliation efficiency:
const char[] _1 = "bob";
char[] *s = *_1;
char[] *t = *_1;
assert(*s == *t)
This is however, not typically the case, e.g.
string P = "BobBob";
string s = P.Substring(0,3);
string t = P.Substring(0,3);
now s and t are distinct in memory - a memory profile would show "Bob" appearing in memory twice.
const char[] _1 = "BobBob";
char[] *s = char[0];
char[] *t = char[0];
String_Substring(*_1, 6, 0, 3, *s);
String_Substring(*_1, 6, 0, 3, *s);
assert(*t != *s) -
evildictaitor wrote:

ScanIAm wrote:
...
Plus, if you attempted to add in the size of the strings, you'd have to try to account for the fact that .NET reuses strings:
string s = "Bob";
string t = "Bob";
There is only 1 copy of "Bob" in memory.
This is due to compliation efficiency:
const char[] _1 = "bob";
char[] *s = *_1;
char[] *t = *_1;
assert(*s == *t)
This is however, not typically the case, e.g.
string P = "BobBob";
string s = P.Substring(0,3);
string t = P.Substring(0,3);
now s and t are distinct in memory - a memory profile would show "Bob" appearing in memory twice.
const char[] _1 = "BobBob";
char[] *s = char[0];
char[] *t = char[0];
String_Substring(*_1, 6, 0, 3, *s);
String_Substring(*_1, 6, 0, 3, *s);
assert(*t != *s)
.NET uses string interning (http://msdn2.microsoft.com/en-us/library/system.string.isinterned.aspx) You can actually specify whether you want to use this or not (its on by default) via an assembly attribute 'CompilationRelaxations(CompilationRelaxations.NoStringInterning)'. -
ScanIAm wrote:

Raghavendra_Mudugal wrote:
now i am more confused...
:scratching-head:
I'm guessing on the number 4, but I believe that it takes 4 bytes to store the reference to the string. If I'm wrong, then change it.
Don't forget 64 bit systems. Pointers on that are double in size.
Thread Closed
This thread is kinda stale and has been closed but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.