Core improvements over original memfs
memefs was rewritten to address critical performance issues in the original WinFsp memfs:Vector-based sector storage
Original memfs: Used heap allocation for every file write, causing severe performance degradation for unpreallocated files (see benchmarks). memefs: Usesstd::vector<Sector*> (sectors.h:13) with a private heap for sector management. This provides:
- Much faster unpreallocated writes: No heap fragmentation from individual allocations
- Predictable memory layout: Sectors stored contiguously in vectors
- Efficient resizing: Vector growth handles most reallocation scenarios
Memory management
memefs uses a dedicated private heap for sector allocations:- Isolated memory allocation: Doesn’t interfere with system heap
- Better locality: Related data allocated together
- Accurate tracking: Know exactly how much memory is used
Performance trade-offs
When to use memefs
Use memefs when you:- Need a constantly-running RAM disk for general file operations
- Download files or create new files without preallocation
- Want dynamic memory allocation (only uses memory actually needed)
- Need reasonable sequential and random I/O performance
- Value stability and modern C++ safety guarantees
When to use original memfs
Use the original memfs when you:- Can preallocate files with
NtCreateFileand itsAllocationSizeparameter - Need maximum sequential write speed for preallocated files
- Have very specific performance requirements for preallocated scenarios
Read/write performance
TheSectorManager::ReadWrite<IsReading>() template handles all I/O:
Read operations (io.cpp:4-24)
- Check if offset is beyond file size
- Calculate end offset (capped at file size)
- Call
ReadWrite<true>()to copy data from sectors to buffer - Return bytes transferred
Write operations (io.cpp:26-65)
- Handle write modes (append, constrained, normal)
- Resize file if needed via
SetFileSizeInternal() - Call
ReadWrite<false>()to copy data from buffer to sectors - Return bytes transferred
Memory limits
Set maximum memory usage with the-s flag:
- Used size: Actual data stored (
GetUsedTotalSize()) - Max size: User-specified limit (
maxFsSize) - Available size: Remaining space (
CalculateAvailableTotalSize())
STATUS_DISK_FULL.
Sector alignment
All allocations are aligned to sector boundaries:- Sector size: 512 bytes (
MEMFS_SECTOR_SIZE) - Alignment: Rounds up to nearest sector boundary
- Overhead: Small files (< 512 bytes) still use 512 bytes
Concurrency
memefs handles concurrent access efficiently:Sector-level locking
EachSectorNode has its own mutex:
- Multiple readers: Concurrent reads from the same file
- Single writer: Exclusive write access per file
- File-level parallelism: Different files accessed simultaneously
File node reference counting
File nodes use atomic reference counting:- Safe concurrent access: Multiple handles to the same file
- Proper cleanup: File deleted only when refcount reaches zero
- No race conditions: Atomic increment/decrement operations
WinFsp dispatcher threading
WinFsp automatically creates a thread pool (typically 8-16 threads) to dispatch operations. memefs is designed to be fully thread-safe.Optimization tips
1. Set appropriate memory limits
Don’t set-s too low or you’ll run out of space. Don’t set it too high or you’ll waste address space:
2. Use case-insensitive mode for compatibility
Windows applications expect case-insensitive file systems:3. Avoid flush-and-purge unless needed
The-f flag forces cache flushes, which can slow down operations:
4. Use NTFS file system name
Some applications check the file system name:5. Preallocate large files if possible
While memefs handles unpreallocated files well, preallocation is still faster for very large files:Cache management
WinFsp integrates with the Windows cache manager:- FileInfoTimeout: 15 seconds (create.cpp:41)
- PostCleanupWhenModifiedOnly: Reduces cleanup overhead (create.cpp:49)
- PostDispositionWhenNecessaryOnly: Reduces disposition overhead (create.cpp:50)
Monitoring performance
To understand performance:- Enable debug logging: Use
-d -1 -D memefs.logto see all operations - Check operation counts: Look at the debug log for operation frequency
- Monitor memory usage: Check Task Manager or Process Explorer
- Run benchmarks: Use tools like fsbench or diskspd
Common performance issues
Issue: Slow writes
Cause: May be hitting memory limit or system memory pressure Solution:- Check available RAM
- Increase
-slimit if too low - Check for memory leaks in your application
Issue: Slow directory enumeration
Cause: Large directories with thousands of files Solution:- memefs uses a map for file storage, which is O(log n) for lookups
- Consider organizing files into subdirectories
- Use directory markers to enumerate in chunks
Issue: High CPU usage
Cause: Too many small I/O operations Solution:- Use larger buffer sizes in your application
- Enable write caching in your application
- Check if antivirus is scanning the RAM disk
Performance compared to physical disks
As a RAM disk, memefs is:- Much faster than traditional HDDs (100-1000x)
- Faster than most SSDs for random I/O
- Similar or faster than NVMe SSDs for sequential I/O
- Limited by RAM speed and CPU memory copy performance