Created attachment 18753 [details]
I came across a possible memory leak issue in one of my assignments and when I dig into the problem, I suspected of Queryable implementation of Mono. I reproduced the leak in the program attached.
I built the program both with .Net and Mono compiler but result did not change. I'm running the program on Ubuntu 14.04, Mono 4.6.2.
When I run the same program on Windows, there is no memory leak.
Also, when I change the line
result = Foos.AsQueryable().FirstOrDefault(foo => foo.Bar == "Bar1");
result = Foos.FirstOrDefault(foo => foo.Bar == "Bar1");
there is no leak.
I can confirm the memory just goes up and up but there is nothing specific in the code so I suspect reflection leak or sgen bug
This is not a gc issue. The leak comes from managed code. More specifically each invocation leads to the compilation of a dynamic method which is leaked.
The first question would be if we care about the leak itself. As far as I know we don't free jit-ed code and I don't think it is in our main priorities. Maybe vargaz can confirm here.
Probably a more important question would be why we emit a method every time we invoke that. The answer to this probably lies in the managed world, related to linq expressions. I've attached another test case which shows great performance difference between 2 ways of accessing the first element of an IQueryable (the .First case does the dyanmic method compilation). I also attached two stack traces one on master and one on an ancient 3.4 that I had, which show the point where the method is created.
Created attachment 19075 [details]
dynamic method creation master and 3.4.1
Created attachment 19076 [details]
dynamic method vs no dynamic method
We attempt to free memory for dynamic methods, but there could be a leak there.