Emurgo / cardano-serialization-lib

This is a library, written in Rust, for serialization & deserialization of data structures used in Cardano's Haskell implementation of Alonzo along with useful utility functions.
Other
234 stars 125 forks source link

Memory leak: calling free() on an object does not free all referenced objects. #578

Closed MarcelKlammer closed 1 year ago

MarcelKlammer commented 1 year ago

Freeing up memory does not seem to work for referenced objects. The memory is slowing increasing, eg. on SundaeSwap, which is calling getUtxos() frequently, keeping a wallet connected results in the wasm memory slowly increasing to 2GB and then crashing.

  for(let i = 0; i < 500000; i++) {

    const bigNum              = CSL.BigNum.from_str('1000000')
    const value               = CSL.Value.new(bigNum)

    // To be clear, value.free() should be freeing all referenced objects, like coin and all multiassets.

    value.coin().free()       // This call does nothing: memory is still increasing
    value.free()              // Frees only CSL.Value properties?

    bigNum.free()             // Adding this call keeps: wasm.memory.buffer.byteLength steady.
  }
MarcelKlammer commented 1 year ago

I narrowed it down to:

CSL.MultiAsset.insert()
CSL.Assets.insert()

Even keeping the return values in an array to later free them, memory increases.

lisicky commented 1 year ago

Hi @MarcelKlammer! In the CSL, if you use an object as an argument, the CSL does not capture the object reference but copies the object's value for internal usage. We do that because we can't control a lifetime of external objects inside our rust codebase.

CSL.Value.new(bigNum)

In your example, when you put bigNum as a CSL's function argument, the function just uses a copy of that bigNum value. And when some CSL's function returns an object, it's not an object that CSL's struct has inside, it's a copy of that object. That's why that code bellow doesn't free the original bigNum variable.

value.coin().free()

Till we don't add auto object freeing, you can use that workaround https://github.com/Emurgo/cardano-serialization-lib/issues/542#issuecomment-1373862988

MarcelKlammer commented 1 year ago

Ok, just to be 100% clear, all returned values of all functions are copies / new objects. And all parameters provided to CSL functions will be copied instead of referenced?

lisicky commented 1 year ago

Unfortunately yes

MarcelKlammer commented 1 year ago

Thanks for the clarification.