meh / rust-tun

TUN device creation and handling.
340 stars 133 forks source link

Memory leak on windows #83

Open tubzby opened 6 months ago

tubzby commented 6 months ago

I'm using the latest version 0.6.1 (asyn api) on Windows, quickly after I finished my code and tested it on Windows 11, I noticed that the memory consumption continued to increase(over 1MB increase in 1 second) and never got freed, so I used Visual Studio to detach to the process and take several memory snapshots to take a close look into this, please check the attached images, from my prospect of view, it's likely coming from wintun crate or even windows crate, can anybody look into this?

img_v3_026r_a75b6543-2049-453a-8efa-9b784a85786g img_v3_026r_8a6e26c5-c44e-4463-8349-93f1450bce6g img_v3_026r_81cbfcfa-39b4-406d-9159-b8491fed712g img_v3_026r_4921b258-cee2-4874-9f8a-c75178c21d6g img_v3_026r_5ba60438-30e3-4e2c-80ee-a1f139f809eg img_v3_026r_b07e603c-53a3-4585-87a0-73552de1f29g img_v3_026r_9270771a-65f3-4ac2-9dd8-b8bf083702bg

e1732a364fed commented 4 months ago

代码上怎么写的呢?直接用的 example 吗

tubzby commented 4 months ago

@e1732a364fed run the example first, it can read/write to the tun interface, anything other than that should be your own job.

e1732a364fed commented 4 months ago

@e1732a364fed run the example first, it can read/write to the tun interface, anything other than that should be your own job.

我是在问,你这个 memory leak 的issue 是由什么代码造成的。你没理解我的意思。比如说,example 的代码是不是就会有你这个 issue 的问题

e1732a364fed commented 4 months ago

@e1732a364fed run the example first, it can read/write to the tun interface, anything other than that should be your own job.

为什么理解中文如此难呢?你的截图中有中文

tubzby commented 4 months ago

@e1732a364fed run the example first, it can read/write to the tun interface, anything other than that should be your own job.

我是在问,你这个 memory leak 的issue 是由什么代码造成的。你没理解我的意思。比如说,example 的代码是不是就会有你这个 issue 的问题

不是example代码,按照自己的需要加的,我看能不能提供一个能重现问题的mini-example

chen2ding commented 3 months ago

内存泄露,有定位到具体原因吗

chen2ding commented 3 months ago

image 这个地方需要判断cached大小,然后在处理数据(图中直接丢弃),否则程序会崩溃

tubzby commented 3 months ago

一直没有处理,我这里不会崩溃,只是内存泄漏。

chen2ding commented 3 months ago

image 把这段删掉就好了,感觉是造成了tokio泄露了

tubzby commented 3 months ago

我也感觉这个地方有问题,一直会启动线程。

tubzby commented 2 months ago

Got the time to look into this lately, the problem is that Queue::poll_read will fork a new thread if no data is ready, but there might be another thread already polling, which may result in a bunch of threads all stuck in polling, cause a memory leak.

The fix is simple, check if the polling thread is running before creating.

The most important thing is that Queue::poll_read might fired multiple times even if the previous poll_read is in Poll::Pending state.

loop {
  // in this case, Queue::poll_read will fire once no more than 10ms, even if no data is available.
  tokio::select!{
    _ = sleep_10ms() => {},
    msg = dev.next() => {},
  }
}