OmniSharp / omnisharp-roslyn

OmniSharp server (HTTP, STDIO) based on Roslyn workspaces
MIT License
1.76k stars 420 forks source link

Performance: editing code source takes forever and process memory increase beyond many Gb #2418

Open thomashilke opened 2 years ago

thomashilke commented 2 years ago

Description

I am working on a pretty large solution (~100 projects, by no means huge, but a couple of native C++ projects and about a dozen C++/CLI projects, the rest C# projects targeting netstandard2.0 or net4.8). Omnisharp performance have never been great on this solution, but recently things have taken a new turn, to the point where Omnisharp is now unusable on this solution.

I also use the combination Emacs+lsp-mode+Emnisharp on many other solutions which are all much smaller (only a few/tens C# projects targeting NetStandard2.0 or Net6.0), and I never experience such performance issues with these solutions.

Unfortunately, I cannot share the impacted solution as it is closed-source, but in my case the reproduction steps are the following. They work 100% of the time.

Repro

  1. Open emacs,
  2. Open a .cs file in the solution,
  3. Wait for lsp-mode to launch Omnisharp, let Omnisharp load all the projects,
  4. Start editing, insert new code that should trigger autocompletion at point.

Result

The responsivity of emacs plunge sharply, new characters trickle on the screen one by one until everything grinds to a halt. Meanwhile, Omnisharp use huge amount of CPU resources, and memory usage raise of multiple Gb steadily over the course of a few minutes. Sometimes the process is killed, forcing Emacs to restart it.

I tried to attach Visual Studio to the process and profile it/take memory snapshots, but for some reason VS keep failing to take snapshots, and CPU analysis takes forever. In the following screenshot, I start writing on the line at the beginning of the session, and at about 15 seconds into the session I am done physically typing a copy of the line above. We see that even after more than 5mn Emacs is still stuck, and Omnisharp busy with the memory growing from about 1Gb to more that 3Gb, without limit.

2137

Once, I could manage to profile the process, an it showed that it spend most of it's time in functions from Roslyn related to symbol lookup, around FindReferencesSearchEngine. Unfortunately, I could not reproduce that trace for now.

Details

Intel Core i7-7820HQ @ 2.9GHz 16 Go RAM Windows 10 10.0.19044 Emacs 29.0.5 lsp-mode 20220702.1309 Omnisharp

thomashilke commented 2 years ago

I had the opportunity to collect a little bit more data. It seems that the behavior is triggered when the list of completion candidate is requested by the client (Emacs / lsp-mode in my case), but also with FindUsage requests as below. By attaching to the process and breaking at random times when Omnisharp is busy and Emacs unresponsive, typical call stacks are looking like this:

Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.DependentTypeFinder.AddMatchingMetadataTypesInMetadataReferenceAsync(System.Collections.Generic.HashSet<Microsoft.CodeAnalysis.INamedTypeSymbol> metadataTypes, Microsoft.CodeAnalysis.Project project, System.Func<Microsoft.CodeAnalysis.INamedTypeSymbol, System.Collections.Generic.HashSet<Microsoft.CodeAnalysis.INamedTypeSymbol>, bool> typeMatches, Microsoft.CodeAnalysis.Compilation compilation, Microsoft.CodeAnalysis.PortableExecutableReference reference, System.Collections.Generic.HashSet<Microsoft.CodeAnalysis.INamedTypeSymbol> result, System.Threading.CancellationToken cancellationToken) Line 433
    at /_/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs(433)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.DependentTypeFinder.AddDescendantMetadataTypesInProjectAsync(System.Collections.Generic.HashSet<Microsoft.CodeAnalysis.INamedTypeSymbol> currentMetadataTypes, System.Collections.Generic.HashSet<Microsoft.CodeAnalysis.INamedTypeSymbol> result, Microsoft.CodeAnalysis.Project project, System.Func<Microsoft.CodeAnalysis.INamedTypeSymbol, System.Collections.Generic.HashSet<Microsoft.CodeAnalysis.INamedTypeSymbol>, bool> typeMatches, System.Func<Microsoft.CodeAnalysis.INamedTypeSymbol, bool> shouldContinueSearching, bool transitive, System.Threading.CancellationToken cancellationToken) Line 397
    at /_/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs(397)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.DependentTypeFinder.DescendInheritanceTreeInProjectAsync(bool searchInMetadata, System.Collections.Generic.HashSet<Microsoft.CodeAnalysis.INamedTypeSymbol> result, System.Collections.Generic.HashSet<Microsoft.CodeAnalysis.INamedTypeSymbol> currentMetadataTypes, System.Collections.Generic.HashSet<Microsoft.CodeAnalysis.INamedTypeSymbol> currentSourceAndMetadataTypes, Microsoft.CodeAnalysis.Project project, System.Func<Microsoft.CodeAnalysis.INamedTypeSymbol, System.Collections.Generic.HashSet<Microsoft.CodeAnalysis.INamedTypeSymbol>, bool> typeMatches, System.Func<Microsoft.CodeAnalysis.INamedTypeSymbol, bool> shouldContinueSearching, bool transitive, System.Threading.CancellationToken cancellationToken) Line 176
    at /_/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs(176)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.DependentTypeFinder.DescendInheritanceTreeAsync(Microsoft.CodeAnalysis.INamedTypeSymbol type, Microsoft.CodeAnalysis.Solution solution, System.Collections.Immutable.IImmutableSet<Microsoft.CodeAnalysis.Project> projects, System.Func<Microsoft.CodeAnalysis.INamedTypeSymbol, System.Collections.Generic.HashSet<Microsoft.CodeAnalysis.INamedTypeSymbol>, bool> typeMatches, System.Func<Microsoft.CodeAnalysis.INamedTypeSymbol, bool> shouldContinueSearching, bool transitive, System.Threading.CancellationToken cancellationToken) Line 141
    at /_/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs(141)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.DependentTypeFinder.FindDerivedClassesInCurrentProcessAsync(Microsoft.CodeAnalysis.INamedTypeSymbol type, Microsoft.CodeAnalysis.Solution solution, System.Collections.Immutable.IImmutableSet<Microsoft.CodeAnalysis.Project> projects, bool transitive, System.Threading.CancellationToken cancellationToken) Line 27
    at /_/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedClasses.cs(27)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.DependentTypeFinder.FindTypesInCurrentProcessAsync(Microsoft.CodeAnalysis.INamedTypeSymbol type, Microsoft.CodeAnalysis.Solution solution, System.Collections.Immutable.IImmutableSet<Microsoft.CodeAnalysis.Project> projects, bool transitive, Microsoft.CodeAnalysis.FindSymbols.DependentTypesKind kind, System.Threading.CancellationToken cancellationToken) Line 71
    at /_/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_Remote.cs(71)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.DependentTypeFinder.FindTypesAsync(Microsoft.CodeAnalysis.INamedTypeSymbol type, Microsoft.CodeAnalysis.Solution solution, System.Collections.Immutable.IImmutableSet<Microsoft.CodeAnalysis.Project> projects, bool transitive, Microsoft.CodeAnalysis.FindSymbols.DependentTypesKind kind, System.Threading.CancellationToken cancellationToken) Line 44
    at /_/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_Remote.cs(44)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.SymbolFinder.FindDerivedClassesArrayAsync(Microsoft.CodeAnalysis.INamedTypeSymbol type, Microsoft.CodeAnalysis.Solution solution, bool transitive, System.Collections.Immutable.IImmutableSet<Microsoft.CodeAnalysis.Project> projects, System.Threading.CancellationToken cancellationToken)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.SymbolFinder.FindDerivedClassesAsync(Microsoft.CodeAnalysis.INamedTypeSymbol type, Microsoft.CodeAnalysis.Solution solution, bool transitive, System.Collections.Immutable.IImmutableSet<Microsoft.CodeAnalysis.Project> projects, System.Threading.CancellationToken cancellationToken) Line 210
    at /_/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy.cs(210)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.SymbolFinder.FindOverridesArrayAsync(Microsoft.CodeAnalysis.ISymbol symbol, Microsoft.CodeAnalysis.Solution solution, System.Collections.Immutable.IImmutableSet<Microsoft.CodeAnalysis.Project> projects, System.Threading.CancellationToken cancellationToken) Line 47
    at /_/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy.cs(47)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.FindReferencesSearchEngine.SymbolSet.AddDownSymbolsAsync(Microsoft.CodeAnalysis.FindSymbols.FindReferencesSearchEngine engine, Microsoft.CodeAnalysis.ISymbol symbol, Microsoft.CodeAnalysis.FindSymbols.MetadataUnifyingSymbolHashSet seenSymbols, System.Collections.Generic.Stack<Microsoft.CodeAnalysis.ISymbol> workQueue, System.Collections.Immutable.ImmutableHashSet<Microsoft.CodeAnalysis.Project> projects, System.Threading.CancellationToken cancellationToken) Line 236
    at /_/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.SymbolSet.cs(236)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.FindReferencesSearchEngine.BidirectionalSymbolSet.InheritanceCascadeAsync(Microsoft.CodeAnalysis.Project project, System.Threading.CancellationToken cancellationToken) Line 51
    at /_/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.BidirectionalSymbolSet.cs(51)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.FindReferencesSearchEngine.FindReferencesAsync(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ISymbol> symbols, System.Threading.CancellationToken cancellationToken) Line 113
    at /_/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs(113)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.SymbolFinder.FindReferencesInCurrentProcessAsync(Microsoft.CodeAnalysis.ISymbol symbol, Microsoft.CodeAnalysis.Solution solution, Microsoft.CodeAnalysis.FindSymbols.IStreamingFindReferencesProgress progress, System.Collections.Immutable.IImmutableSet<Microsoft.CodeAnalysis.Document> documents, Microsoft.CodeAnalysis.FindSymbols.FindReferencesSearchOptions options, System.Threading.CancellationToken cancellationToken) Line 72
    at /_/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Current.cs(72)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.SymbolFinder.FindReferencesAsync(Microsoft.CodeAnalysis.ISymbol symbol, Microsoft.CodeAnalysis.Solution solution, Microsoft.CodeAnalysis.FindSymbols.IStreamingFindReferencesProgress progress, System.Collections.Immutable.IImmutableSet<Microsoft.CodeAnalysis.Document> documents, Microsoft.CodeAnalysis.FindSymbols.FindReferencesSearchOptions options, System.Threading.CancellationToken cancellationToken) Line 43
    at /_/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Current.cs(43)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.SymbolFinder.FindReferencesAsync(Microsoft.CodeAnalysis.ISymbol symbol, Microsoft.CodeAnalysis.Solution solution, Microsoft.CodeAnalysis.FindSymbols.FindReferencesSearchOptions options, System.Threading.CancellationToken cancellationToken) Line 44
    at /_/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Legacy.cs(44)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.SymbolFinder.FindReferencesAsync(Microsoft.CodeAnalysis.ISymbol symbol, Microsoft.CodeAnalysis.Solution solution, System.Threading.CancellationToken cancellationToken) Line 33
    at /_/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Legacy.cs(33)
OmniSharp.Roslyn.CSharp.dll!OmniSharp.Roslyn.CSharp.Services.Navigation.FindUsagesService.Handle(OmniSharp.Models.FindUsages.FindUsagesRequest request) Line 53
    at D:\a\1\s\src\OmniSharp.Roslyn.CSharp\Services\Navigation\FindUsagesService.cs(53)
OmniSharp.Cake.dll!OmniSharp.Cake.Services.RequestHandlers.CakeRequestHandler<OmniSharp.Models.FindUsages.FindUsagesRequest, OmniSharp.Models.QuickFixResponse>.Handle(OmniSharp.Models.FindUsages.FindUsagesRequest request) Line 57
    at D:\a\1\s\src\OmniSharp.Cake\Services\RequestHandlers\CakeRequestHandler.cs(57)
OmniSharp.LanguageServerProtocol.dll!OmniSharp.LanguageServerProtocol.Handlers.OmniSharpCodeLensHandler.Handle(OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens request, System.Threading.CancellationToken token) Line 77
    at D:\a\1\s\src\OmniSharp.LanguageServerProtocol\Handlers\OmniSharpCodeLensHandler.cs(77)
OmniSharp.Extensions.JsonRpc.dll!OmniSharp.Extensions.JsonRpc.JsonRpcServerServiceCollectionExtensions.RequestHandlerDecorator<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens, OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens>.Handle(OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens request, System.Threading.CancellationToken cancellationToken)
OmniSharp.Extensions.LanguageServer.dll!OmniSharp.Extensions.LanguageServer.Server.Pipelines.SemanticTokensDeltaPipeline<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens, OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens>.Handle(OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens request, System.Threading.CancellationToken cancellationToken, MediatR.RequestHandlerDelegate<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens> next)
OmniSharp.Extensions.LanguageServer.dll!OmniSharp.Extensions.LanguageServer.Server.Pipelines.ResolveCommandPipeline<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens, OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens>.Handle(OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens request, System.Threading.CancellationToken cancellationToken, MediatR.RequestHandlerDelegate<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens> next)
MediatR.dll!MediatR.Pipeline.RequestPreProcessorBehavior<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens, OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens>.Handle(OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens request, System.Threading.CancellationToken cancellationToken, MediatR.RequestHandlerDelegate<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens> next)
MediatR.dll!MediatR.Pipeline.RequestPostProcessorBehavior<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens, OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens>.Handle(OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens request, System.Threading.CancellationToken cancellationToken, MediatR.RequestHandlerDelegate<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens> next)
MediatR.dll!MediatR.Pipeline.RequestExceptionProcessorBehavior<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens, OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens>.Handle(OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens request, System.Threading.CancellationToken cancellationToken, MediatR.RequestHandlerDelegate<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens> next)
MediatR.dll!MediatR.Pipeline.RequestExceptionActionProcessorBehavior<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens, OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens>.Handle(OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens request, System.Threading.CancellationToken cancellationToken, MediatR.RequestHandlerDelegate<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens> next)
MediatR.dll!MediatR.Internal.RequestHandlerWrapperImpl<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens, OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens>.Handle(MediatR.IRequest<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens> request, System.Threading.CancellationToken cancellationToken, MediatR.ServiceFactory serviceFactory)
MediatR.dll!MediatR.Mediator.Send<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens>(MediatR.IRequest<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens> request, System.Threading.CancellationToken cancellationToken)
OmniSharp.Extensions.JsonRpc.dll!OmniSharp.Extensions.JsonRpc.RequestRouterBase<OmniSharp.Extensions.LanguageServer.Protocol.Shared.ILspHandlerDescriptor>.SendRequest<OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens, OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens>(MediatR.IMediator mediator, OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens request, System.Threading.CancellationToken token)
[Native to Managed Transition]
[Managed to Native Transition]
OmniSharp.Extensions.JsonRpc.dll!OmniSharp.Extensions.JsonRpc.RequestRouterBase<OmniSharp.Extensions.LanguageServer.Protocol.Shared.ILspHandlerDescriptor>.HandleRequest(MediatR.IMediator mediator, OmniSharp.Extensions.JsonRpc.IHandlerDescriptor descriptor, object params, System.Threading.CancellationToken token)
OmniSharp.Extensions.JsonRpc.dll!OmniSharp.Extensions.JsonRpc.RequestRouterBase<OmniSharp.Extensions.LanguageServer.Protocol.Shared.ILspHandlerDescriptor>.RouteRequest.__InnerRoute|5_0(Microsoft.Extensions.DependencyInjection.IServiceScopeFactory serviceScopeFactory, OmniSharp.Extensions.JsonRpc.Server.Request request, OmniSharp.Extensions.LanguageServer.Protocol.Shared.ILspHandlerDescriptor descriptor, object params, System.Threading.CancellationToken token, Microsoft.Extensions.Logging.ILogger logger)
OmniSharp.Extensions.JsonRpc.dll!OmniSharp.Extensions.JsonRpc.RequestRouterBase<OmniSharp.Extensions.LanguageServer.Protocol.Shared.ILspHandlerDescriptor>.RouteRequest(OmniSharp.Extensions.JsonRpc.IRequestDescriptor<OmniSharp.Extensions.LanguageServer.Protocol.Shared.ILspHandlerDescriptor> descriptors, OmniSharp.Extensions.JsonRpc.Server.Request request, System.Threading.CancellationToken token)
OmniSharp.Extensions.LanguageServer.Shared.dll!OmniSharp.Extensions.LanguageServer.Shared.LspRequestRouter.OmniSharp.Extensions.JsonRpc.IRequestRouter<OmniSharp.Extensions.JsonRpc.IHandlerDescriptor>.RouteRequest(OmniSharp.Extensions.JsonRpc.IRequestDescriptor<OmniSharp.Extensions.JsonRpc.IHandlerDescriptor> descriptors, OmniSharp.Extensions.JsonRpc.Server.Request request, System.Threading.CancellationToken token)
OmniSharp.Extensions.JsonRpc.dll!OmniSharp.Extensions.JsonRpc.InputHandler.RouteRequest.AnonymousMethod__5(System.Threading.CancellationToken ct)
System.Reactive.dll!System.Reactive.Linq.QueryLanguage.StartAsyncImpl<OmniSharp.Extensions.JsonRpc.ErrorResponse>(System.Func<System.Threading.CancellationToken, System.Threading.Tasks.Task<OmniSharp.Extensions.JsonRpc.ErrorResponse>> functionAsync, System.Reactive.Concurrency.IScheduler scheduler) Line 727
    at /_/Rx.NET/Source/src/System.Reactive/Linq/QueryLanguage.Async.cs(727)
System.Reactive.dll!System.Reactive.Linq.ObservableImpl.Defer<OmniSharp.Extensions.JsonRpc.ErrorResponse>._.Run() Line 38
    at /_/Rx.NET/Source/src/System.Reactive/Linq/Observable/Defer.cs(38)
System.Reactive.dll!System.Reactive.Producer<OmniSharp.Extensions.JsonRpc.ErrorResponse, System.Reactive.Linq.ObservableImpl.Defer<OmniSharp.Extensions.JsonRpc.ErrorResponse>._>.SubscribeRaw(System.IObserver<OmniSharp.Extensions.JsonRpc.ErrorResponse> observer, bool enableSafeguard) Line 128
    at /_/Rx.NET/Source/src/System.Reactive/Internal/Producer.cs(128)
System.Reactive.dll!System.Reactive.Sink<OmniSharp.Extensions.JsonRpc.ErrorResponse, OmniSharp.Extensions.JsonRpc.ErrorResponse>.Run(System.IObservable<OmniSharp.Extensions.JsonRpc.ErrorResponse> source) Line 89
    at /_/Rx.NET/Source/src/System.Reactive/Internal/Sink.cs(89)
System.Reactive.dll!System.Reactive.Linq.ObservableImpl.AmbCoordinator<OmniSharp.Extensions.JsonRpc.ErrorResponse>.Subscribe(System.IObservable<OmniSharp.Extensions.JsonRpc.ErrorResponse>[] sources) Line 96
    at /_/Rx.NET/Source/src/System.Reactive/Linq/Observable/AmbMany.cs(96)
System.Reactive.dll!System.Reactive.Linq.ObservableImpl.AmbCoordinator<OmniSharp.Extensions.JsonRpc.ErrorResponse>.Create(System.IObserver<OmniSharp.Extensions.JsonRpc.ErrorResponse> observer, System.IObservable<OmniSharp.Extensions.JsonRpc.ErrorResponse>[] sources) Line 91
    at /_/Rx.NET/Source/src/System.Reactive/Linq/Observable/AmbMany.cs(91)
System.Reactive.dll!System.Reactive.BasicProducer<OmniSharp.Extensions.JsonRpc.ErrorResponse>.SubscribeRaw(System.IObserver<OmniSharp.Extensions.JsonRpc.ErrorResponse> observer, bool enableSafeguard) Line 66
    at /_/Rx.NET/Source/src/System.Reactive/Internal/Producer.cs(66)
OmniSharp.Extensions.JsonRpc.dll!OmniSharp.Extensions.JsonRpc.InputHandler.RouteRequest.AnonymousMethod__1(System.IObserver<OmniSharp.Extensions.JsonRpc.ErrorResponse> observer)
System.Reactive.dll!System.Reactive.Linq.QueryLanguage.CreateWithDisposableObservable<OmniSharp.Extensions.JsonRpc.ErrorResponse>.SubscribeCore(System.IObserver<OmniSharp.Extensions.JsonRpc.ErrorResponse> observer) Line 35
    at /_/Rx.NET/Source/src/System.Reactive/Linq/QueryLanguage.Creation.cs(35)
System.Reactive.dll!System.Reactive.ObservableBase<OmniSharp.Extensions.JsonRpc.ErrorResponse>.Subscribe(System.IObserver<OmniSharp.Extensions.JsonRpc.ErrorResponse> observer) Line 58
    at /_/Rx.NET/Source/src/System.Reactive/ObservableBase.cs(58)
System.Reactive.dll!System.Reactive.Linq.ObservableImpl.Select<OmniSharp.Extensions.JsonRpc.ErrorResponse, System.Reactive.Unit>.Selector.Run(System.Reactive.Linq.ObservableImpl.Select<OmniSharp.Extensions.JsonRpc.ErrorResponse, System.Reactive.Unit>.Selector._ sink) Line 22
    at /_/Rx.NET/Source/src/System.Reactive/Linq/Observable/Select.cs(22)
System.Reactive.dll!System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Select<OmniSharp.Extensions.JsonRpc.ErrorResponse, System.Reactive.Unit>.Selector._>.SubscribeRaw(System.IObserver<System.Reactive.Unit> observer, bool enableSafeguard) Line 128
    at /_/Rx.NET/Source/src/System.Reactive/Internal/Producer.cs(128)
System.Reactive.dll!System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.__Canon>.Run(System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.__Canon>._ sink) Line 87
    at /_/Rx.NET/Source/src/System.Reactive/Linq/Observable/Catch.cs(87)
System.Reactive.dll!System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, OmniSharp.Extensions.JsonRpc.Server.RequestCancelledException>._>.SubscribeRaw(System.IObserver<System.Reactive.Unit> observer, bool enableSafeguard) Line 128
    at /_/Rx.NET/Source/src/System.Reactive/Internal/Producer.cs(128)
System.Reactive.dll!System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.__Canon>.Run(System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.__Canon>._ sink) Line 87
    at /_/Rx.NET/Source/src/System.Reactive/Linq/Observable/Catch.cs(87)
System.Reactive.dll!System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, OmniSharp.Extensions.JsonRpc.Server.ContentModifiedException>._>.SubscribeRaw(System.IObserver<System.Reactive.Unit> observer, bool enableSafeguard) Line 128
    at /_/Rx.NET/Source/src/System.Reactive/Internal/Producer.cs(128)
System.Reactive.dll!System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.__Canon>.Run(System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.__Canon>._ sink) Line 87
    at /_/Rx.NET/Source/src/System.Reactive/Linq/Observable/Catch.cs(87)
System.Reactive.dll!System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.OperationCanceledException>._>.SubscribeRaw(System.IObserver<System.Reactive.Unit> observer, bool enableSafeguard) Line 128
    at /_/Rx.NET/Source/src/System.Reactive/Internal/Producer.cs(128)
System.Reactive.dll!System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.__Canon>.Run(System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.__Canon>._ sink) Line 87
    at /_/Rx.NET/Source/src/System.Reactive/Linq/Observable/Catch.cs(87)
System.Reactive.dll!System.Reactive.Concurrency.Scheduler.ScheduleAction.AnonymousMethod__75_0(System.Reactive.Concurrency.IScheduler _, (System.Action<(System.__Canon, System.__Canon)> action, (System.__Canon, System.__Canon) state) tuple) Line 65
    at /_/Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Simple.cs(65)
System.Reactive.dll!System.Reactive.Concurrency.CurrentThreadScheduler.Schedule<(System.Action<(System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._)>, (System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._))>((System.Action<(System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._)>, (System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._)) state, System.TimeSpan dueTime, System.Func<System.Reactive.Concurrency.IScheduler, (System.Action<(System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._)>, (System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._)), System.IDisposable> action) Line 101
    at /_/Rx.NET/Source/src/System.Reactive/Concurrency/CurrentThreadScheduler.cs(101)
System.Reactive.dll!System.Reactive.Concurrency.LocalScheduler.Schedule<(System.Action<(System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._)>, (System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._))>((System.Action<(System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._)>, (System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._)) state, System.Func<System.Reactive.Concurrency.IScheduler, (System.Action<(System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._)>, (System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._)), System.IDisposable> action) Line 32
    at /_/Rx.NET/Source/src/System.Reactive/Concurrency/LocalScheduler.cs(32)
System.Reactive.dll!System.Reactive.Concurrency.Scheduler.ScheduleAction<(System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._)>(System.Reactive.Concurrency.IScheduler scheduler, (System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._) state, System.Action<(System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._)> action) Line 61
    at /_/Rx.NET/Source/src/System.Reactive/Concurrency/Scheduler.Simple.cs(61)
System.Reactive.dll!System.Reactive.Producer<System.Reactive.Unit, System.Reactive.Linq.ObservableImpl.Catch<System.Reactive.Unit, System.Exception>._>.SubscribeRaw(System.IObserver<System.Reactive.Unit> observer, bool enableSafeguard) Line 128
    at /_/Rx.NET/Source/src/System.Reactive/Internal/Producer.cs(128)
System.Reactive.dll!System.Reactive.Linq.ObservableImpl.Merge<System.Reactive.Unit>.Observables._.OnNext(System.IObservable<System.Reactive.Unit> value) Line 179
    at /_/Rx.NET/Source/src/System.Reactive/Linq/Observable/Merge.cs(179)
System.Reactive.dll!System.Reactive.Subjects.FastImmediateObserver<System.IObservable<System.Reactive.Unit>>.EnsureActive(int count) Line 858
    at /_/Rx.NET/Source/src/System.Reactive/Subjects/ReplaySubject.cs(858)
System.Reactive.dll!System.Reactive.Subjects.ReplaySubject<System.IObservable<System.Reactive.Unit>>.ReplayBase.OnNext(System.IObservable<System.Reactive.Unit> value) Line 277
    at /_/Rx.NET/Source/src/System.Reactive/Subjects/ReplaySubject.cs(277)
OmniSharp.Extensions.JsonRpc.dll!OmniSharp.Extensions.JsonRpc.ProcessScheduler..ctor.AnonymousMethod__3((OmniSharp.Extensions.JsonRpc.RequestProcessType type, string name, OmniSharp.Extensions.JsonRpc.SchedulerDelegate request) item)
System.Reactive.dll!System.Reactive.AnonymousObserver<(OmniSharp.Extensions.JsonRpc.RequestProcessType, System.__Canon, System.__Canon)>.OnNextCore((OmniSharp.Extensions.JsonRpc.RequestProcessType, System.__Canon, System.__Canon) value) Line 67
    at /_/Rx.NET/Source/src/System.Reactive/AnonymousObserver.cs(67)
System.Reactive.dll!System.Reactive.ObserverBase<(OmniSharp.Extensions.JsonRpc.RequestProcessType, System.__Canon, System.__Canon)>.OnNext((OmniSharp.Extensions.JsonRpc.RequestProcessType, System.__Canon, System.__Canon) value) Line 36
    at /_/Rx.NET/Source/src/System.Reactive/ObserverBase.cs(36)
System.Reactive.dll!System.Reactive.Subjects.Subject<(OmniSharp.Extensions.JsonRpc.RequestProcessType, string, OmniSharp.Extensions.JsonRpc.SchedulerDelegate)>.OnNext((OmniSharp.Extensions.JsonRpc.RequestProcessType, string, OmniSharp.Extensions.JsonRpc.SchedulerDelegate) value) Line 148
    at /_/Rx.NET/Source/src/System.Reactive/Subjects/Subject.cs(148)
OmniSharp.Extensions.JsonRpc.dll!OmniSharp.Extensions.JsonRpc.InputHandler.HandleRequest(System.Buffers.ReadOnlySequence<byte> request)
OmniSharp.Extensions.JsonRpc.dll!OmniSharp.Extensions.JsonRpc.InputHandler.ProcessInputStream(System.Threading.CancellationToken cancellationToken)
[Resuming Async Method]
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 980
    at f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs(980)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 928
    at f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs(928)
mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run() Line 1070
    at f:\dd\ndp\clr\src\BCL\system\runtime\compilerservices\AsyncMethodBuilder.cs(1070)
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 980
    at f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs(980)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 928
    at f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs(928)
mscorlib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() Line 1252
    at f:\dd\ndp\clr\src\BCL\system\threading\threadpool.cs(1252)
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Line 820
    at f:\dd\ndp\clr\src\BCL\system\threading\threadpool.cs(820)
[Async Call Stack]
[Async] mscorlib.dll!System.Threading.Tasks.Task.ContinueWith
    at f:\dd\ndp\clr\src\BCL\system\threading\Tasks\TaskContinuation.cs(50)

Almost always the process is busy doing stuff below Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.FindSymbols.SymbolFinder.FindReferencesAsync(Microsoft.CodeAnalysis.ISymbol symbol, Microsoft.CodeAnalysis.Solution solution, System.Threading.CancellationToken cancellationToken) Line 33 at /_/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Legacy.cs(33)

So, to me it looks like the problem is more likely related to Microsoft.CodeAnalysis, and not Omnisharp's fault.

denosaurtrain commented 2 years ago

As a troubleshooting step for folks running into omnisharp performance problems in vscode or otherwise, this script may prove useful: https://github.com/fatso83/dotfiles/blob/master/utils/scripts/inotify-consumers. The script output for me shows hundreds of thousands of file handles:

image

You mention having non-C# projects in your repo, which is the case for me as well. My repo isn't particularly large, but I suspect that omnisharp is creating file watch handles on the build artifacts for other languages. Perhaps files.watcherExclude isn't being handled properly or perhaps the language server isn't cleaning up properly (considering the script output shows several instances running simultaneously). What's weirder is that I have "omnisharp.autoStart": false, so I wonder why all those instances were started in the first place.

I don't have a workaround at the moment, but I'm not actively doing C# development, so I can disable the extension for now.