2016年05月4日 エンジニアリング

"There are two hard problems in .NET, caching expressions and naming things"

By Martijn Laarman

We recently released NEST 2.3.1 that contains an important fix for a memory leak NEST users are very likely to hit. We urge everyone on any NEST 2.x version to upgrade to 2.3.1. If you are making the jump from NEST 1.x, please jump straight to NEST 2.3.1 which will work against any Elasticsearch 2.x release.

The memory leak happened in the caching of Expressions which are used throughout the NEST API to have strongly typed expressions to CLR type properties relating to fields in a document. For example,

var response = client.Search<Project>(s => s
    .Query(q => q
        .Term(c => c
            .Field(p => p.Name)
            .Value("project description")
        )
    )
)

Here we have a reference to the "name" field in Elasticsearch using the Lambda expression, p => p.Name. Because of a bug in our Field's GetHashCode() implementation, the dictionary in which resolved expressions are cached would grow unbounded during the lifetime of the AppDomain.

We profile extensively and are halfway through adding profile results and their differences in our CI pipeline, but unfortunately this did not catch this leak in longer running applications. The low level client, Elasticsearch.Net, was not affected by this bug.

Nearly three years ago I was served a slice of humble pie through a GitHub issue reporting a regression, and today we've been served another. We would like to thank Alex, Rasmus Mikkelsen, Lars Sorensen and Kristian Jensen for raising and confirming the issue.

If you have any questions, please don't hesitate to reach out to us either on Twitter or GitHub. We sincerely apologize for any inconvenience this may have caused!