Skip to content
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

Validate method call hangs #133

Closed
Havunen opened this issue Jun 4, 2019 · 16 comments
Closed

Validate method call hangs #133

Havunen opened this issue Jun 4, 2019 · 16 comments
Labels
bug Something isn't working
Milestone

Comments

@Havunen
Copy link
Contributor

Havunen commented Jun 4, 2019

Hi!

When calling container.Validate() method dryIoc seems to allocate memory until everything is gone and crashes the application. We have large application so its difficult to give exact steps to reproduce the issue, but I will continue investigating and post here the findings.

We are using following DryIoc packages:

dryioc.webapi.owin 4.0.0
dryioc.webapi 4.0.0
dryioc.web 4.0.0
dryioc.mvc 4.0.0
dryioc 4.0.4

image

We are first registering our services and then calling container.Validate() method. This call seems to take forever and eventually crashes due to system being out of memory.

I have collected some call stacks of the issue by pausing it using debugger.
Stack1:

App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73
	at \DryIoc\Expression.cs(73)
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837
	at \DryIoc\Expression.cs(837)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854
	at \DryIoc\Expression.cs(854)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852
	at \DryIoc\Expression.cs(852)
App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToLambdaExpression() Line 1229
	at \DryIoc\Expression.cs(1229)
App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToExpression() Line 1226
	at \DryIoc\Expression.cs(1226)
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73
	at \DryIoc\Expression.cs(73)
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837
	at \DryIoc\Expression.cs(837)
App.Ioc.dll!FastExpressionCompiler.LightExpression.MethodCallExpression.ToExpression() Line 893
	at \DryIoc\Expression.cs(893)
App.Ioc.dll!FastExpressionCompiler.LightExpression.UnaryExpression.ToExpression() Line 566
	at \DryIoc\Expression.cs(566)
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73
	at \DryIoc\Expression.cs(73)
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837
	at \DryIoc\Expression.cs(837)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854
	at \DryIoc\Expression.cs(854)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852
	at \DryIoc\Expression.cs(852)
App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToLambdaExpression() Line 1229
	at \DryIoc\Expression.cs(1229)
App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToExpression() Line 1226
	at \DryIoc\Expression.cs(1226)
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73
	at \DryIoc\Expression.cs(73)
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837
	at \DryIoc\Expression.cs(837)
App.Ioc.dll!FastExpressionCompiler.LightExpression.MethodCallExpression.ToExpression() Line 893
	at \DryIoc\Expression.cs(893)
App.Ioc.dll!FastExpressionCompiler.LightExpression.UnaryExpression.ToExpression() Line 566
	at \DryIoc\Expression.cs(566)
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73
	at \DryIoc\Expression.cs(73)
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837
	at \DryIoc\Expression.cs(837)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854
	at \DryIoc\Expression.cs(854)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852
	at \DryIoc\Expression.cs(852)
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73
	at \DryIoc\Expression.cs(73)
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837
	at \DryIoc\Expression.cs(837)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854
	at \DryIoc\Expression.cs(854)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852
	at \DryIoc\Expression.cs(852)
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73
	at \DryIoc\Expression.cs(73)
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837
	at \DryIoc\Expression.cs(837)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854
	at \DryIoc\Expression.cs(854)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852
	at \DryIoc\Expression.cs(852)
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73
	at \DryIoc\Expression.cs(73)
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837
	at \DryIoc\Expression.cs(837)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854
	at \DryIoc\Expression.cs(854)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852
	at \DryIoc\Expression.cs(852)
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73
	at \DryIoc\Expression.cs(73)
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837
	at \DryIoc\Expression.cs(837)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854
	at \DryIoc\Expression.cs(854)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852
	at \DryIoc\Expression.cs(852)
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73
	at \DryIoc\Expression.cs(73)
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837
	at \DryIoc\Expression.cs(837)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854
	at \DryIoc\Expression.cs(854)
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852
	at \DryIoc\Expression.cs(852)
App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToLambdaExpression() Line 1229
	at \DryIoc\Expression.cs(1229)
App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToExpression() Line 1226
	at \DryIoc\Expression.cs(1226)
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73
	at \DryIoc\Expression.cs(73)
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837
	at \DryIoc\Expression.cs(837)
App.Ioc.dll!FastExpressionCompiler.LightExpression.MethodCallExpression.ToExpression() Line 893
	at \DryIoc\Expression.cs(893)
App.Ioc.dll!FastExpressionCompiler.LightExpression.UnaryExpression.ToExpression() Line 566
	at \DryIoc\Expression.cs(566)
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression<DryIoc.FactoryDelegate>.ToLambdaExpression() Line 1252
	at \DryIoc\Expression.cs(1252)
App.Ioc.dll!DryIoc.ContainerTools.GenerateResolutionExpressions(DryIoc.IContainer container, System.Func<System.Collections.Generic.IEnumerable<DryIoc.ServiceRegistrationInfo>, System.Collections.Generic.IEnumerable<DryIoc.ServiceInfo>> getRoots, bool allowRuntimeState) Line 3115
	at \DryIoc\Container.cs(3115)
App.Ioc.dll!DryIoc.ContainerTools.Validate(DryIoc.IContainer container, System.Func<DryIoc.ServiceRegistrationInfo, bool> condition) Line 3150
	at \DryIoc\Container.cs(3150)
Web.App.Rest.API.dll!App.Rest.API.WebApiConfig.Register(System.Web.Http.HttpConfiguration config) Line 54
	at C:\git\App3\Web.App.Rest.API\App_Start\WebApiConfig.vb(54)
Web.App.Rest.API.dll!App.Rest.API.Startup.Configuration(Owin.IAppBuilder app) Line 30
	at C:\git\App3\Web.App.Rest.API\Startup.vb(30)
[External Code]

Stack2:

App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToLambdaExpression() Line 1229	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToExpression() Line 1226	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.MethodCallExpression.ToExpression() Line 893	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.UnaryExpression.ToExpression() Line 566	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToLambdaExpression() Line 1229	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToExpression() Line 1226	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.MethodCallExpression.ToExpression() Line 893	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.UnaryExpression.ToExpression() Line 566	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToLambdaExpression() Line 1229	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToExpression() Line 1226	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.MethodCallExpression.ToExpression() Line 893	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.UnaryExpression.ToExpression() Line 566	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToNewExpression() Line 854	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.NewExpression.ToExpression() Line 852	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToLambdaExpression() Line 1229	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.LambdaExpression.ToExpression() Line 1226	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression.ToExpressions(System.Collections.Generic.IReadOnlyList<FastExpressionCompiler.LightExpression.Expression> exprs) Line 73	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.ArgumentsExpression.ArgumentsToExpressions() Line 837	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.MethodCallExpression.ToExpression() Line 893	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.UnaryExpression.ToExpression() Line 566	C#
App.Ioc.dll!FastExpressionCompiler.LightExpression.Expression<DryIoc.FactoryDelegate>.ToLambdaExpression() Line 1252	C#
App.Ioc.dll!DryIoc.ContainerTools.GenerateResolutionExpressions(DryIoc.IContainer container, System.Func<System.Collections.Generic.IEnumerable<DryIoc.ServiceRegistrationInfo>, System.Collections.Generic.IEnumerable<DryIoc.ServiceInfo>> getRoots, bool allowRuntimeState) Line 3115	C#
App.Ioc.dll!DryIoc.ContainerTools.Validate(DryIoc.IContainer container, System.Func<DryIoc.ServiceRegistrationInfo, bool> condition) Line 3150	C#
Web.App.Rest.API.dll!App.Rest.API.WebApiConfig.Register(System.Web.Http.HttpConfiguration config) Line 54	Basic
Web.App.Rest.API.dll!App.Rest.API.Startup.Configuration(Owin.IAppBuilder app) Line 30	Basic
[External Code]	

We are running on .Net 4.6.1 Framework.

@Havunen
Copy link
Contributor Author

Havunen commented Jun 4, 2019

It seems like its going through root class System.Web.Http.ApiController inside GenerateResolutionExpressions method when the jamm happens

https://github.com/dadhi/DryIoc/blob/master/src/DryIoc/Container.cs#L3100-L3106

variable root is:
ServiceType = {Name = "ApiController" FullName = "System.Web.Http.ApiController"}

@dadhi
Copy link
Owner

dadhi commented Jun 4, 2019

Thanks for letting me know. Will check.

@Havunen
Copy link
Contributor Author

Havunen commented Jun 4, 2019

hmm, It might be that this is not actually infinite loop. It just takes enormous amount of memory to complete Validate() operation. There are 1914 root objects and after 838 iterations it needs 20Gb Ram, but it actually goes forward.

@Havunen Havunen changed the title Validate falls into infinite loop Validate method call hangs Jun 4, 2019
@Havunen
Copy link
Contributor Author

Havunen commented Jun 4, 2019

After inspecting the values more I noticed there are some strange types in the roots list.

For example there is 152 objects of following type:

{ApiControllerBase {ServiceKey=DefaultKey(0)}}	DryIoc.ServiceInfo {DryIoc.ServiceInfo.WithDetails}
{ApiControllerBase {ServiceKey=DefaultKey(1)}}	DryIoc.ServiceInfo {DryIoc.ServiceInfo.WithDetails}
{ApiControllerBase {ServiceKey=DefaultKey(2)}}	DryIoc.ServiceInfo {DryIoc.ServiceInfo.WithDetails}
...
{ApiControllerBase {ServiceKey=DefaultKey(152)}}	DryIoc.ServiceInfo {DryIoc.ServiceInfo.WithDetail}

And 153 objects of IHttpController type:

{IHttpController {ServiceKey=DefaultKey(0)}}	DryIoc.ServiceInfo {DryIoc.ServiceInfo.WithDetails}
{IHttpController {ServiceKey=DefaultKey(1)}}	DryIoc.ServiceInfo {DryIoc.ServiceInfo.WithDetails}
{IHttpController {ServiceKey=DefaultKey(2)}}	DryIoc.ServiceInfo {DryIoc.ServiceInfo.WithDetails}
...
{IHttpController {ServiceKey=DefaultKey(153)}}	DryIoc.ServiceInfo {DryIoc.ServiceInfo.WithDetails}

Those are base classes for our Rest controllers, which inherit from our ApiControllerBase which inherits from System.Web.Http.ApiController and that implements IHttpController type.

Are those types supposed to be there that many times? It seems like all the top level controller types are there also HeartbeatController, FilesController etc.

@Havunen
Copy link
Contributor Author

Havunen commented Jun 4, 2019

After filtering out those types, the Validate call went through 20.5GB RAM used. Strange thing is that GC is not cleaning it up. I need to kill IIS process to free the memory. So this might be memory leak bug actually.

5minutes after Validate call:
image

@dadhi
Copy link
Owner

dadhi commented Jun 4, 2019

May be we can do some filtering in Validate. You may specify the specific roots.

@Havunen
Copy link
Contributor Author

Havunen commented Jun 4, 2019

I just installed dotMemory, I need to check why its allocating so much and why its not cleaning the objects.

@dadhi
Copy link
Owner

dadhi commented Jun 4, 2019

I see many ToExpression conversion calls in the stack trace. So, try to run
container.With(rules => rules.WithoutFastExpressionCompiler()).Validate(...).
Hmm, you don't need the FEC for Validate as you don't compile anything. I will fix it in DryIoc.

@Havunen
Copy link
Contributor Author

Havunen commented Jun 4, 2019

image

Retention view from dotMemory shows the reason for GC not cleaning the memory.

@Havunen
Copy link
Contributor Author

Havunen commented Jun 5, 2019

@dadhi I created Container class following way:

(visual basic)

Dim container = New Container(Function(rules) rules.WithoutFastExpressionCompiler().With(FactoryMethod.ConstructorWithResolvableArguments)).WithWebApi(config)

And memory usage is still huge.

@dadhi
Copy link
Owner

dadhi commented Jun 5, 2019

Thanks for checking

@Havunen
Copy link
Contributor Author

Havunen commented Jun 5, 2019

This issue occurs because GenerateResolutionExpressions is adding all roots to Results.Root (GeneratedExpressions)

And those Roots hold reference to other expressions, causing my Computer 32Gb Ram not being enough to handle validation call. When not adding the Roots to result object ( which validation does not use them anyway ) then it goes through using 2gb ram.

Old:

                    result.Roots.Add(root.Pair(expr.WrapInFactoryExpression()
#if SUPPORTS_FAST_EXPRESSION_COMPILER
                        .ToLambdaExpression()
#endif
                    ));

Changed:

                    root.Pair(expr.WrapInFactoryExpression()
#if SUPPORTS_FAST_EXPRESSION_COMPILER
                        .ToLambdaExpression()
#endif
                    );

But this is public API and same issue would happen when directly calling
container.GenerateResolutionExpressions(...)

Is there some reason why roots need to hold reference to all generated objects disallowing GC to remove them?

@dadhi
Copy link
Owner

dadhi commented Jun 5, 2019

Is there some reason why roots need to hold reference to all generated objects disallowing GC to remove them?

Hmm, maybe not. Validate is based on GenerateResolutionExpressions which goal is to collect
expressions for compile-time generation. But Validate itself does not need it.
I think this can be fixed then.

@dadhi dadhi added the bug Something isn't working label Jun 5, 2019
@dadhi dadhi added this to the v4.0.5 milestone Jun 5, 2019
@dadhi dadhi closed this as completed in 898c2c5 Jun 7, 2019
@dadhi
Copy link
Owner

dadhi commented Jun 7, 2019

@Havunen,

I have fixed both #133 and #134 and released v4.0.5-preview-01.
Could you please check. If everything is working I will release v4.0.5.

@Havunen
Copy link
Contributor Author

Havunen commented Jun 8, 2019

Validation is really fast now and barely uses any memory! This is working :)

@dadhi
Copy link
Owner

dadhi commented Jun 8, 2019

DryIoc v4.0.5 is released on NuGet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants