-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Assembly.Load opens /dev/zero in linux and does not close it #47859
Comments
Are you opening /dev/zero, or do you think it is being opened by something within .NET? Can you share your code? |
We do not open /dev/zero stream in our code.
And it very strange that Razor asks and opens new stream of Shared files (like layout, viewimport etc) several times due one page. We can not share the code, because it is very big corporate system. We try to determinate place in code. Will touch you on progress. |
Are you properly closing the file handles (disposing the file handling objects) after using them? |
After the long time of investigation we found out the reason. Steps to reproduce:
P.S. May be we should move this issue to asp repo? |
Thanks, that's helpful. @Pilchie can you help route |
This issue was moved to dotnet/aspnetcore#17395 |
Hi @Pilchie @carlossanlop Here code to reproduce
after line We deepened to code inside the framework, file
and dll import
The LoadFromStream opens IntPtr and does not close it.
AspRuntimeCompilation loads assembly with the same way while processing and compile views. |
Another code snippet to observe the issue. Memory consumption just keeps climbing. Also, when calling context.Unload() I get an ExecutionEngineException? ` class Program
` |
Is there any progress on this issue? We are using |
Would you mind please reopening this issue for it does not seem to be aspnet-related? We are not using aspnet, but are affected by this problem still |
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
@jeffschwMSFT - can you help route within runtime? |
Tagging subscribers to this area: @vitek-karas, @agocke, @CoffeeFlux Issue Detailstoo many files open error in linuxAfter several hours of work web application on cent os 7 gets error "Too many files open" GeneralAfter each request to my application the system opens and keep open a lot of /dev/zero files. System InfoOS LINUX X64 Linux 3.10.0-1062.4.1.el7.x86_64 dotnet/core#1 SMP Fri Oct 18 17:15:30 UTC 2019 Cent OS 7
|
I can reproduce this. Yes |
Nope, while the return type seems incorrect, that is not the reason for the leak. Fixing that does no fix the problem. |
Opening I think it is no longer needed and should be removed to avoid running into fd limits. The main reason for the leak though is that assemblies loaded via |
The following example, which uses unloadable context, does not have the issue. using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Text;
namespace TestAssemblyLoad
{
class Program
{
private static readonly Encoding Encoding = Encoding.UTF8;
private static readonly CSharpParseOptions ParseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest);
private static readonly CSharpCompilationOptions CompilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
private static readonly ConcurrentDictionary<string, MetadataReference> References = new ConcurrentDictionary<string, MetadataReference>();
static Program()
{
var referencedAssemblies = Assembly.GetEntryAssembly().GetReferencedAssemblies();
foreach (var referencedAssembly in referencedAssemblies)
AddReference(referencedAssembly);
}
private static void AddReference(AssemblyName assemblyName)
{
var assembly = Assembly.Load(assemblyName);
References.TryAdd(assembly.Location, MetadataReference.CreateFromFile(assembly.Location));
var referencedAssemblyNames = assembly.GetReferencedAssemblies();
foreach (var referencedAssemblyName in referencedAssemblyNames)
{
var referencedAssembly = Assembly.Load(referencedAssemblyName);
References.TryAdd(referencedAssembly.Location, MetadataReference.CreateFromFile(referencedAssembly.Location));
}
}
static void Main(string[] args)
{
Console.WriteLine("PID: " + Process.GetCurrentProcess().Id);
Console.ReadKey();
Run(@"using System;
public class SubProgram
{
public static void Main()
{
Console.Write(""."");
}
}");
Console.WriteLine("The end...");
Console.ReadKey();
}
public static void Run(string code)
{
var assemblyName = nameof(Assembly) + "_" + Guid.NewGuid().ToString("N");
var syntaxTrees = new List<SyntaxTree>();
var embeddedTexts = new List<EmbeddedText>();
var filePath = $"{nameof(Assembly)}_file_{Guid.NewGuid():N}.cs";
var buffer = Encoding.GetBytes(code);
var sourceText = SourceText.From(buffer, buffer.Length, Encoding, canBeEmbedded: true);
var syntaxTree = CSharpSyntaxTree.ParseText(sourceText, ParseOptions, filePath);
var embeddedText = EmbeddedText.FromSource(filePath, sourceText);
syntaxTrees.Add(syntaxTree);
embeddedTexts.Add(embeddedText);
var compilation = CSharpCompilation.Create(
assemblyName,
syntaxTrees: syntaxTrees,
references: References.Values,
options: CompilationOptions);
var emitOptions = new EmitOptions(
debugInformationFormat: DebugInformationFormat.PortablePdb,
pdbFilePath: Path.ChangeExtension(assemblyName, "pdb"));
using var stream = new MemoryStream();
using var symbolsStream = new MemoryStream();
var emitResult = compilation.Emit(stream, symbolsStream, embeddedTexts: embeddedTexts, options: emitOptions);
if (emitResult.Success)
{
stream.Seek(0, SeekOrigin.Begin);
symbolsStream.Seek(0, SeekOrigin.Begin);
}
var streamArr = stream.ToArray();
var symbolsStreamArr = symbolsStream.ToArray();
var assembly = Assembly.Load(streamArr, symbolsStreamArr);
for(int i= 0; i < 100000000; i++)
{
// THIS WOULD NOT UNLOAD !!!
// Assembly.Load(streamArr, symbolsStreamArr);
stream.Seek(0, SeekOrigin.Begin);
symbolsStream.Seek(0, SeekOrigin.Begin);
var alc = new AssemblyLoadContext(null, isCollectible: true);
Assembly a = alc.LoadFromStream(stream, symbolsStream);
ProcessStartInfo pi = new ProcessStartInfo();
pi.UseShellExecute = true;
pi.FileName = "/usr/bin/lsof";
pi.Arguments = " /dev/zero";
Process.Start(pi);
Console.ReadKey();
var type = assembly.GetType("SubProgram");
var method = type.GetMethod("Main");
method.Invoke(null, null);
alc.Unload();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
Process.Start(pi);
}
stream.Dispose();
symbolsStream.Dispose();
}
}
} |
I think we still need to get rid of opening |
fixed in #48140 |
too many files open error in linux
After several hours of work web application on cent os 7 gets error "Too many files open"
General
After each request to my application the system opens and keep open a lot of /dev/zero files.
I run command
lsof | grep zero | wc -l
and looking out that count of files increase and increase.System Info
OS LINUX X64 Linux 3.10.0-1062.4.1.el7.x86_64 dotnet/core#1 SMP Fri Oct 18 17:15:30 UTC 2019 Cent OS 7
.NET Core 3.0.0
The text was updated successfully, but these errors were encountered: