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

asynchronous drawImage speeds up execution but causes serious memory leaks. #890

Open
rambo-panda opened this issue Sep 9, 2024 · 8 comments
Assignees

Comments

@rambo-panda
Copy link
Contributor

// this is pmap status
0000000000400000    7644    3104       0 r---- node
0000000000b77000       8       8       0 r-x-- node
0000000000b7a000   27296   13892       0 r-x-- node
0000000002800000       4       0       0 r-x-- node
0000000002801000   46796    8980       0 r---- node
00000000055b4000      16      16       8 r---- node
00000000055b8000     124     108      92 rw--- node
00000000055d7000     180     168     168 rw---   [ anon ]
00000000075e0000 5697364 5697132 5697132 rw---   [ anon ]
00000266d94c0000     256     256     256 rw---   [ anon ]
0000033e93480000     256       8       8 rw---   [ anon ]
0000036b35cc0000     256     256     256 rw---   [ anon ]
0000039136800000     256     256     256 rw---   [ anon ]
000003f309900000     256     256     256 rw---   [ anon ]
000004103ff00000     256     256     256 rw---   [ anon ]

image
The memory does not automatically drop to normal levels, even though I have enabled GC and cleared all cache.

@rambo-panda
Copy link
Contributor Author

#867

@Horziox
Copy link

Horziox commented Sep 9, 2024

After several tests on my side and after proceeding by elimination, I confirm I have the same issue.
The buffers generated by drawImage cannot be cleared by Node's Garbage Collector, inevitably leading to a memory leak.

@Brooooooklyn Brooooooklyn self-assigned this Sep 10, 2024
@bingtsingw
Copy link

I have the same issue

@rambo-panda
Copy link
Contributor Author

canvas/src/image.rs

Lines 417 to 424 in 8ca3a9e

let this: This = env.get_reference_value(&self.this_ref)?;
let mut image_ptr = ptr::null_mut();
check_status!(
unsafe { sys::napi_unwrap(env.raw(), this.raw(), &mut image_ptr) },
"Failed to unwrap Image from this"
)?;
let self_mut = unsafe { Box::leak(Box::from_raw(image_ptr.cast::<Image>())) };
self_mut.width = output.width;

// 'static pointer
let self_mut = unsafe { Box::leak(Box::from_raw(image_ptr.cast::<Image>())) }; 

@rambo-panda
Copy link
Contributor Author

rambo-panda commented Sep 12, 2024

canvas/src/image.rs

Lines 417 to 424 in 8ca3a9e

let this: This = env.get_reference_value(&self.this_ref)?;
let mut image_ptr = ptr::null_mut();
check_status!(
unsafe { sys::napi_unwrap(env.raw(), this.raw(), &mut image_ptr) },
"Failed to unwrap Image from this"
)?;
let self_mut = unsafe { Box::leak(Box::from_raw(image_ptr.cast::<Image>())) };
self_mut.width = output.width;

// 'static pointer
let self_mut = unsafe { Box::leak(Box::from_raw(image_ptr.cast::<Image>())) }; 

@Brooooooklyn since I have limited understanding of @napi-rs, I am hesitant to change the lifecycle of self_mut rashly. Is it possible to make the following modification for the time being?

  #[napi(setter)]
  pub fn set_src(&mut self, env: Env, this: This, data: Uint8Array) -> Result<()> {
    let length = data.len();
    if length <= 2 {
      self.src = Some(data);
+     self.bitmap = None;
+     self.width = -1.0;
+      self.height = -1.0;

Of course, I have my own motives, as it just happens to meet another need of mine. #868

@rambo-panda

This comment was marked as resolved.

@rambo-panda

This comment was marked as resolved.

@bingtsingw
Copy link

@Brooooooklyn Hi, are there any progress on this issue, it's a serious problem on server, after a few requests, the server memory usage is full.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants