Rhino Compute service memory leak

Hi, I’m developing a application service using Rhino.Compute
and reference : https://github.com/mcneel/compute.rhino3d/blob/master/src/compute.geometry/ResthopperEndpoints.cs

During service startup, it reads grasshopper file and extract definition (type : GH_Document).
Then when api request occurs, it receives input data and compute related objects using input.
Since the service reuses same definition without calling Dispose() method, memory increases for each time when api request is handled.

As a temporary solution, I made my service restart after certain number of api request calls.

From memory profiling result, it says Grasshopper.Kernel.GH_DocumentServer.DocumentRemovedEventHandler
object is not released, which causes memory increase.
Is there a way to reuse same definition object without calling Dispose()?
Or any way to release object causing memory leak?

Hey @evan12,

Dropping in to say I’m experiencing similar issues. I’m putting a test project together for @stevebaer or whoever else to look at. Attempting to resuse a single GH_Document instance hasn’t quelled the problem.

@evan12 It would be helpful to compare notes. Could you upload a test project as well here?

So it appears that GH_Document isn’t able to be fully disposed of because of events that haven’t been unregistered. I used ANTS to profile:

image

I also saw a malignant event GumballPreview something something.

Thanks Leland, I’ll start digging into this.

I’m having trouble figuring out how to replicate this so if you have any sort of test project I would appreciate it.

@stevebaer:

Put this project together that simulates the key aspects of how we use resthopper:

  • sending a single large json payload and injecting it into the definition
  • sending bundles of payloads which is simulated by the console app

The big string sent here is a dummy lorem ipsum passage. Every time a new request is sent, memory builds and builds and seems not to be released. Memory allocation does wind down eventually, but when a new request is made it balloons back up to essentially where it left off.

To run:

  • build the geo service and the test app (send-json-gh-request)
  • start the geometry service, then run the test app
  • you can configure the test app to send as many serial requests you want.

Amendments to canonical copy of resthopper:

  • fixed string input conversion in ResthopperEndpoints
  • changed location of Rhino WIP from Rhino 7 WIP to Rhino WIP. You may need to change this back on your end.

The gh document is embedded in the test request as b64 string and packaged with the attached project.

compute.rhino3d.zip (1.3 MB)

Thanks; I’ll take a look

Hey @Leland_Jobson,
I think I found where the memory is stacking up. Try placing the var definition = new GH_Document(); in a using statement

This fix has been added to the compute repo

Steve,

Appreciate the look - thank you! I have tried this solution in our own implementation with no luck…are you seeing memory being released on your end when you try this?

Yes, I was just watching task manager and it looked like explicitly forcing a Dispose() call through the using statement was keeping memory usage stable. I could crank up the number of tests with your sample app (I had it go through 10 calls).

I wouldn’t be surprised if memory was being kept around for your more “real world” use case, but at least this fix is a step in the right direction.

Hi, as Leland described, applying fixed code doesn’t seem to solve the problem.
(Actually, I was already calling GH_Document.Dispose() explicitly at the end of resthopper call, which didn’t solve the problem)

GC takes memory down to certain level, but this level slightly increases for each api call.

Executing resthopper api call 200 times makes execution time twice longer in average.

Are you passing curves, surfaces, breps, or meshes as input ? Or having these returned as output? I see another spot where we aren’t properly disposing GeometryBase instances when the grasshopper endpoint is complete. I can try to fix that today.

Hey @Leland_Jobson, maybe try running ants profiler again with the change to Dispose() the document to see if you get different results.

I’m also planning on visiting you guys next week. Maybe we can spend a few minutes on this topic.

Steve,

Great news - thanks for looking into this. When I get a chance to load test the server I will be sure to make a profile. I’ll try to have something to look at for when you get here. Cheers!