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

Memory Leak 8.2.2 when using Odata to communicate with Business Central #1371

Open
MikkelGlerup opened this issue Dec 10, 2024 · 6 comments
Open
Assignees
Labels
bug Something isn't working P1

Comments

@MikkelGlerup
Copy link

Our project is using .NET8
Odata 8.2.2

When running our project, each time the code does retrieves or saves data in Business Central through Odata the memory usage goes up without ever coming down:

var newOrderQuery = new DataServiceCollection<MtSalesInvoice>(_mtApiContext.MtSalesInvoices.Where(s => s.Id == new Guid("11111111-1111-1111-1111-111111111111")));
 var newOrder = new MtSalesInvoice();
 newOrderQuery.Add(newOrder);
 newOrder.CustomerNumber = existingCustomer.Number;
 newOrder.InvoiceDate = DateTime.Now.Date;
 newOrder.UniqueReference = locator;
 newOrder.IsMarkedForInvoiceCheck = operation.Order.IsMarkedForInvoiceCheck;
 _mtApiContext.SaveChanges(SaveChangesOptions.PostOnlySetProperties);

 _mtApiContext.Detach(newOrderQuery);

image

looking at memory heap most of it not all memory is being taken by Odata.

@MikkelGlerup MikkelGlerup added the bug Something isn't working label Dec 10, 2024
@mikepizzo
Copy link
Member

Did you notice this as a regression from a previous version, or do you know if the same issue occurs in earlier versions?

@corranrogue9
Copy link
Contributor

corranrogue9 commented Dec 10, 2024

@MikkelGlerup the most common reason for memory issues in the OData client is having entity tracking enabled. This issue is exacerbated if you are also creating a new instance of your data service context (_mtApiContext in your case) instance for each client request. If you disable entity tracking on the machine that is executing the client, does that resolve your memory issue?

@corranrogue9 corranrogue9 self-assigned this Dec 10, 2024
@MikkelGlerup
Copy link
Author

Did you notice this as a regression from a previous version, or do you know if the same issue occurs in earlier versions?

We had the same problem running 7.2, however I didn't look more into how much, since I read that 8.0 had memory optimization and decided to update

@MikkelGlerup
Copy link
Author

@MikkelGlerup the most common reason for memory issues in the OData client is having entity tracking enabled. This issue is exacerbated if you are also creating a new instance of your data service context (_mtApiContext in your case) instance for each client request. If you disable entity tracking on the machine that is executing the client, does that resolve your memory issue?

how do I disable entity tracking in this case?

unfortunately we don't create new instances of our data service contexts. This was my first thought, and to be sure I double checked just now.

@habbes
Copy link
Contributor

habbes commented Dec 12, 2024

@MikkelGlerup If you're using a single instance of the DataServiceContext throughout your app, and your process is long-running, and client-tracking is enabled, then it's possible that the DataServiceContext's entity tracker can grow in size over time (e.g. each time it fetches entities from the server, if those entities will be stored and cached on the client side in the local entity tracker if they don't already exist in the tracker). It's hard to tell whether that's what your service is facing without having additional information such as screenshot of the memory profiler's snapshot of objects in memory, or a repro project that demonstrates the issue. It would also be good to force garbage collection and see if memory use goes down, or if it says up even after full GC.

That said, you could disable entity tracking and see if that helps:

new MyDataServiceContextClass
{
   MergeOption = MergeOption.NoTracking
}

PS: If this fixes the problem we should have an article about this in our performance guidelines docs: MicrosoftDocs/OData-docs#317

@MikkelGlerup
Copy link
Author

MikkelGlerup commented Dec 12, 2024

@habbes
Even if we detach the object every time like so:
image

This finally is run at the end of every operation.

I'd love to use

new MyDataServiceContextClass
{
   MergeOption = MergeOption.NoTracking
}

However with the way Business Central uses Odata it is impossible. You'd get errors telling you how the object you're saving has already changed if it is not tracked.

Memory heap:
image
image
image
image
image
image
image
image

It would also be good to force garbage collection and see if memory use goes down, or if it says up even after full GC.

I've already tried testing this through the code snippet I screenshot first, and nothing changed, well except the memory which rose 😄

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

No branches or pull requests

4 participants