cornerstoneWADOImageLoader icon indicating copy to clipboard operation
cornerstoneWADOImageLoader copied to clipboard

Memory problems and long load times for multiframe ultrasound data

Open dereklukacs opened this issue 2 years ago • 16 comments

Hello @dannyrb you seem most active on this problem, after several days of debugging I too am having issues loading Multiframe Ultrasound data. I have compiled a list of related issues from this repo at the bottom.

In my case I have RGB encoded, 400mb, 204 frame Ultrasound data in a single multiframe DCM file with transfer syntax 1.2.840.10008.1.2.1

Config:

var config = {
  maxWebWorkers: 1,
  startWebWorkersOnDemand: false,
  taskConfiguration: {
    decodeTask: {
      initializeCodecsOnStartup: false,
      loadCodecsOnStartup: false,
      usePDFJS: false,
      strict: false,
    },
  },
  webWorkerTaskPaths: [
    'https://unpkg.com/[email protected]/dist/610.bundle.min.worker.js',
    'https://unpkg.com/[email protected]/dist/888.bundle.min.worker.js',
  ],
};

A few observations:

  • The per-frame load time (after the network call finishes) appears to scale with the size of the source file (dataset). I experience near-instant loads with a 12 frame file. Intermediate per-frame load times for a 100mb fluoroscopy file. ~1 sec / frame load times for the 400 mb file described above.
  • If I throttle the decoding to the above configuration (load/initializeCodecs: false, maxWebWorkers:1) and only request one frame at a time before requesting for another (no queueing in webWorkerManager) then usually I can load all frames (this takes several minutes). Sometimes though the garbage collection seems to stop working and the memory will quickly climb to take up everything on my machine (16gb available, crashes around 15gb).
  • After crashing, the memory will never get cleared
  • Manually hitting the garbage collection button on chrome dev tools wipes this 15gb down to <1gb.
  • running a profile on loading indicates that ~97% of the time is spent doing postMessage, seems like a lot of overheard for using webworkers.

Conclusions/Deductions from above observations

  • For each frame request, a fully copy of the source dataset is being made
  • The data is freed, but for some reason not being properly garbage collected, even after a very long time

What does a solution look like:

  1. A fix to reduce memory allocation and time taken to load/decode a single frame
  2. A bulk decode method that decodes all of the frames, even it is blocking.
  3. A way to decode without the use of webworkers (and without allocating new memory)

Related issues

#235 #425 #411 https://github.com/cornerstonejs/cornerstoneWADOImageLoader/issues/156#issuecomment-794628050 https://github.com/cornerstonejs/cornerstoneWADOImageLoader/issues/428 #373

https://github.com/cornerstonejs/cornerstone/issues/576 https://github.com/cornerstonejs/cornerstone/issues/519

dereklukacs avatar Apr 12 '22 13:04 dereklukacs

i'd do this progressively using wasm/emscripten. Your last two points can be solved using pthreads to decode all frames which would be done off the main browser thread (non-blocking) and in-effect it would use less memory.

nullhook avatar Apr 16 '22 21:04 nullhook

Thanks for the reply @nullhook, I am not sure I understand what you mean though. Isn't this package already running everything on wasm?

dereklukacs avatar Apr 18 '22 01:04 dereklukacs

i believe it uses web workers to decode frames not wasm.

based on this file it looks like wasm port is in progress and doesn't work yet.

edit: I do see some decoders with wasm imports. however, i still think this can be improved if frames were decoded on the gpu

nullhook avatar Apr 18 '22 02:04 nullhook

@dereklukacs do you have the file in question to upload?

Ouwen avatar Jun 22 '22 20:06 Ouwen

This is related to issue #71 To free the worker memory, I use this code cornerstoneWADOImageLoader.webWorkerManager.terminate();

nyacoub avatar Jul 03 '22 18:07 nyacoub

@Ouwen I cannot share unfortunately.

@nyacoub Yes that seems precisely related and we have also noticed it being worse in chrome. I'll try your proposed workaround. Thanks!

dereklukacs avatar Jul 04 '22 10:07 dereklukacs

#454

@dereklukacs does this PR fix your issue?

Ouwen avatar Jul 05 '22 18:07 Ouwen

Hi @Ouwen I'll try this out today, based on the description it sounds like it should fix the issue.

dereklukacs avatar Jul 12 '22 18:07 dereklukacs

@nyacoub

This seems to help fix the runaway memory problems, thanks!

dereklukacs avatar Jul 12 '22 21:07 dereklukacs

@dereklukacs @Ouwen
could you please let me know how can I use this solution to solve out of memory problem ?

muhammedmokbel avatar Aug 09 '22 09:08 muhammedmokbel

Hi @muhammedmokbel you'll need to run the following steps.

  1. Clone this repo with the above fix
  2. Run npm run build within the root of this repo
  3. Run yarn link within the root of this repo
  4. Run yarn link cornerstone-wado-image-loader in the Viewer or the repo(s) you are working in.

Ouwen avatar Aug 10 '22 07:08 Ouwen

sorry for being late @Ouwen thank you so much

muhammedmokbel avatar Aug 16 '22 20:08 muhammedmokbel

This is related to issue #71 To free the worker memory, I use this code cornerstoneWADOImageLoader.webWorkerManager.terminate();

@nyacoub could you please tell us where we can use this code?

chengfeng311 avatar Aug 25 '22 10:08 chengfeng311

@chengfeng311 use this after retrieving the image. It will kill the workers and free up the memory. In some cases, the memory usage will is high due to the encoder's workers, but the code above will free up that memory and the browser will not crash!

nyacoub avatar Aug 26 '22 00:08 nyacoub

Thanks for reply, but which not solve my problem, I terminate webworker after loaded all images, but when i switch image with cornerstone.loadImage, memory still raise 2%. Do you have any way to solve this problem? @nyacoub

chengfeng311 avatar Aug 26 '22 10:08 chengfeng311

Might need to use chrome memory profiler to take a look

Ouwen avatar Aug 28 '22 15:08 Ouwen