Comments (4)
Making Capacity long isn't possible (note it's an override). Writing a repro test currently so I can validate a fix.
from microsoft.io.recyclablememorystream.
I didn't notice that Capacity is an overridden property from MemoryStream when i encountered the problem. Makes me wonder why the property RecyclableMemoryStreamManager.MaximumStreamCapacity is a long, though. Shouldn't it be an int as well? (Unless you plan to introduce something like RecyclableMemoryStream.CapacityLong, with the overridden MemoryStream.Capacity value being clamped to [0,int.MaxValue], perhaps. But that on the other hand might also perhaps cause bizarre problems for programs who rely on MemoryStream properties such as Position or Length always being <= int.MaxValue. Hmm...)
from microsoft.io.recyclablememorystream.
Unfortunately, there is still an issue when RecyclableMemoryStream with a size close to or exactly of int.MaxValue is being requested.
The commit from June 30th attempts clamping the property RecyclableMemoryStream.Capacity to prevent it from overflowing:
long size = this.blocks.Count * this.memoryManager.BlockSize;
return (int)Math.Min(int.MaxValue, size);
However, the calculation of the long variable size
is incorrect. It will multiply two int values, and will only convert the int result to an long value. Thus, the overflow can still happen and the variable size
becoming negative in the if the block count is becoming sufficiently high.
An example:
When requesting a RecyclableMemoryStream with size of int.MaxValue
, the block count will eventually reach 16384 (assuming the standard block size of 131072).
The int multiplication 16384*131072 will result in the size
variable (and in consequence the Capacity
property) having a negative value of -2147483648. This will break the while loop in the method RecyclableMemoryStream.EnsureCapacity, which again would lead to exhaustion of the available virtual memory.
Suggested fix:
To fix the issue, the multiplication needs to be forced to operate on longs. Casting one or both of the multiplicands/multipliers as a long will do this:
long size = (long) this.blocks.Count * this.memoryManager.BlockSize;
return (int)Math.Min(int.MaxValue, size);
Additionally, the test method GiantAllocationSucceeds is not able to find this issue.
To detect this issue (using the default block size of 128KB), the requested stream size must be at least int.MaxValue - (mgr.BlockSize + 2)
.
The reason why the unit test fails to find this issue is the following: int.MaxValue equals 0x7fffffff. To satisfy a requested stream size of 0x7fffffff with the default block size of 128KB (=0x20000), 16384 blocks are required. Note that the last block is not fully used, its used capacity is 0x1ffff.
However, the largest stream size requested by the unit test is only int.MaxValue - (mgr.BlockSize + 1)
.
(mgr.BlockSize + 1)
equals 0x1ffff - which means only 16383 blocks are needed.
With only needing 16383 blocks, the unit test fails to test a scenario where the RecyclableMemoryStream.Capacity
property could overflow (i.e., scenarios where 16384 blocks would be needed).
I would suggest to let the unit test request a stream size of exactly int.MaxValue to make sure that the clamping of the Capacity property works. If it works with a stream size of int.MaxValue then it should also work with any other stream sizes (as they can only be less than int.MaxValue).
from microsoft.io.recyclablememorystream.
Pretty sure the PR above resolves this per the comment (thank you for the excellent diagnosis). Will give a few days for someone to review before just merging in case any concerns arise. Thanks!
from microsoft.io.recyclablememorystream.
Related Issues (20)
- Continous benchmarking HOT 1
- Multiple StreamManagers in referenced libraries - how to find total memory usage HOT 1
- Large pool limit should apply to whole pool, not each slot HOT 1
- Humanitarian Organization Team mbrgi
- ResponseTime is almost doubled with RecyclableMemoryStream. HOT 5
- Question: GetStream copy existing buffer use case HOT 1
- How effective is this package for buffers that are usually smaller than 256 bytes? HOT 1
- Consider using ArrayPool<byte> as underlying storage mechanism HOT 4
- Breaking changes at 3.0.0 version break OfficeOpenXml NuGet package HOT 11
- Guideline about cryptography with RMS HOT 5
- Unclear Documentation for MaximumFreeSmallPoolBytes
- Upgrade blocker: Recent change of GetStream() to return RecyclableMemoryStream instead of MemoryStream HOT 1
- why just pool MemoryStream HOT 2
- FileStreamResult: ObjectDisposedException: Cannot access a disposed object. HOT 4
- For many small stream writes, RecyclableMemoryStream is slower than other implementations HOT 4
- ETW event source is not working HOT 2
- Use of RecyclableMemoryStreamManager with Confluent.Kafka HOT 2
- RecyclableMemoryStream.TryGetBuffer causes infinite loop when UseExponentialLargeBuffer is true HOT 3
- Does RecycleMemoryStream support data streams larger than 2GB? HOT 1
- Missing `[RequiresUnreferencedCodeAttribute]` annotation for trimming HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from microsoft.io.recyclablememorystream.