Hello Joe,
Joe Feser said:
I know but as I was saying, if you just keep appending a 512 byte array,
when the object goes to allocate the 16mb array, it blows up.
I think that is because internally when extending the memory stream a
complete new byte array is created, which at a certain time exceeds the
"critical point". See source of rotor of the memory stream:
public virtual int Capacity {
get {
if (!_isOpen) __Error.StreamIsClosed();
return _capacity - _origin;
}
set {
if (!_isOpen) __Error.StreamIsClosed();
if (value != _capacity) {
if (!_expandable) __Error.MemoryStreamNotExpandable();
if (value < _length) throw new
ArgumentOutOfRangeException("value",
Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
if (value > 0) {
byte[] newBuffer = new byte[value];
if (_length > 0) Buffer.InternalBlockCopy(_buffer, 0,
newBuffer, 0, _length);
_buffer = newBuffer;
}
else {
_buffer = null;
}
_capacity = value;
}
}
}
I had to put a special case in my loop looking for the Capacity of the
MemoryStream.
This is a hack but did fix the problem for now.
Hopefully it can be fixed.
Did you reproduce it on another OS?
I know it was strange that only at 16mb range did it blow and not anything
bigger, like 32,000,000 or even 24,000,000
It could be an allocation issue, what is really wild is the fact every bit
of memory is taken by the system, all in the matter of 1/100 of a second,
the line spikes in Windows task manager.
Lets hope someone can shed some light on this one, I am shocked it has not
come up more often.
Yeah, same wondering here...
Greetings from f.. cold again Germany
(I don't smoke inside, I know what I'm talking about...)
;-)
Klaus
Klaus Löffelmann said:
Joe,
it's not the problem of MemoryStream, which just occupies the given amount
of bytes in a byte-array. It's a problem of System.Array. Try to
allocate
a
byte (or whatever array is derived from System.Array) -array, it will
produce the same error. Try to allocate it with 32.000.000, it's running
fine.
Weird.
In my opinion it's a bug in the internal handler of System.Array (With
Rotor, I tried to track it down to InternalCreate which resolves in
COMArrayInfo::CreateInstace, which calles AllocateArrayEx) - but
honestly. what's happening there is beyond my comprehension...
Klaus
And if you change the code to
32000000
it will not throw an exception.
this does not allow you to just let the MemoryStream just do it's thing.
Just pointing this out to show it's not the machine.
Over 800mb are allocated with the ms.Capacity = 16776704 call.
Joe
This very simple code throws an error on an XP Box running sp1 and all
the
latest hot fixes.
All the memory in the machine is allocated and you must exit the
application.
try
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
ms.Capacity = 16776704;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
"System.OutOfMemoryException: Exception of type
System.OutOfMemoryException
was thrown."
Any clue?
It can also be reproduced if you keep writing a 512 byte array
into
the
MemoryStream until ensureCapacity tries to set the internal byte[]
length
to
16776704
Joe Feser