Reduce memory used by open file streams

Allocating 1 MB for each file stream was causing memory usage
during the install of certain lists to exceed 60 GB.  This is
primarily due to BSA/BA2 creation where tens of thousands of files
are open at the same time.  Additionally, there appears to be a
couple file stream leaks where file streams are not closed until
the entire program is closed.

There appears to still be some discussion on how this affects
performance and a proper fix.  This is more of a dirty "make it work
for more users" fix so people can stop messing with their page files.
This commit is contained in:
Chris Bessent 2021-01-18 06:13:14 -07:00
parent 4a32fc1415
commit e2d5a42254

View File

@ -177,7 +177,7 @@ namespace Wabbajack.Common
{
if (otherPath.Exists && overwrite)
await otherPath.DeleteAsync();
await CopyToAsync(otherPath);
await DeleteAsync();
return;
@ -190,7 +190,7 @@ namespace Wabbajack.Common
public RelativePath RelativeTo(AbsolutePath p)
{
var relPath = Path.GetRelativePath(p._path, _path);
if (relPath == _path)
if (relPath == _path)
throw new ArgumentException($"{_path} is not a subpath of {p._path}");
return new RelativePath(relPath);
}
@ -262,7 +262,7 @@ namespace Wabbajack.Common
// ignore, it doesn't exist so why delete it?
}
}
public void Delete()
{
if (!IsFile) return;
@ -310,7 +310,7 @@ namespace Wabbajack.Common
public AbsolutePath Combine(params string[] paths)
{
return new AbsolutePath(Path.Combine(paths.Cons(_path).ToArray()));
}
@ -344,9 +344,9 @@ namespace Wabbajack.Common
public async ValueTask HardLinkIfOversize(AbsolutePath destination)
{
if (!destination.Parent.Exists)
if (!destination.Parent.Exists)
destination.Parent.CreateDirectory();
if (Root == destination.Root && Consts.SupportedBSAs.Contains(Extension))
{
if (HardLinkTo(destination))
@ -398,14 +398,14 @@ namespace Wabbajack.Common
{
var path = _path;
return CircuitBreaker.WithAutoRetryAsync<FileStream, IOException>(async () =>
File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, bufferSize: 1048576, useAsync: true));
File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, bufferSize: 4096, useAsync: true));
}
public ValueTask<FileStream> WriteShared()
{
var path = _path;
return CircuitBreaker.WithAutoRetryAsync<FileStream, IOException>(async () =>
File.Open(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite, bufferSize: 1048576, useAsync: true));
File.Open(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite, bufferSize: 4096, useAsync: true));
}
public async Task CopyDirectoryToAsync(AbsolutePath destination)