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

[bug] Memory leak when emitting events #12724

Open
lanyeeee opened this issue Feb 17, 2025 · 0 comments
Open

[bug] Memory leak when emitting events #12724

lanyeeee opened this issue Feb 17, 2025 · 0 comments
Labels
status: needs triage This issue needs to triage, applied to new issues type: bug

Comments

@lanyeeee
Copy link

lanyeeee commented Feb 17, 2025

Describe the bug

When continuously emitting events from the backend to the frontend, the memory usage grows substantially.
In my test case, after emitting 2 million events:

  • Frontend memory usage reaches approximately 1.1GB
  • Backend memory usage reaches approximately 120MB

Reproduction

1. Create a new Tauri project

pnpm create tauri-app
.../195129c6cbb-5d34                     |   +2 +
.../195129c6cbb-5d34                     | Progress: resolved 12, reused 2, downloaded 0, added 2, done
✔ Project name · tauri-app
✔ Identifier · com.tauri-app.app
✔ Choose which language to use for your frontend · TypeScript / JavaScript - (pnpm, yarn, npm, deno, bun)
✔ Choose your package manager · pnpm
✔ Choose your UI template · Vanilla
✔ Choose your UI flavor · TypeScript

2. Replace the source files with this

// lib.rs
use tauri::Emitter;

// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}! You've been greeted from Rust!", name)
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_opener::init())
        .invoke_handler(tauri::generate_handler![greet])
        .setup(|app| {
            let app = app.handle().clone();
            tauri::async_runtime::spawn(async move {
                tokio::time::sleep(std::time::Duration::from_secs(5)).await;
                for i in 0..2000000 {
                    if let Err(err) = app.emit("test", i) {
                        eprintln!("{i}: {err}");
                    }
                    // sleep for a second every 10000 iterations
                    if i % 10000 == 0 {
                        tokio::time::sleep(std::time::Duration::from_secs(1)).await;
                    }
                }
            });

            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
# Cargo.toml
[package]
name = "tauri-app"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
# The `_lib` suffix may seem redundant but it is necessary
# to make the lib name unique and wouldn't conflict with the bin name.
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
name = "tauri_app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]

[build-dependencies]
tauri-build = { version = "2", features = [] }

[dependencies]
tauri = { version = "2", features = [] }
tauri-plugin-opener = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"

tokio = { version = "1.43.0", features = ["full"] }
// main.ts
import {invoke} from "@tauri-apps/api/core";
import {listen} from "@tauri-apps/api/event";

let greetInputEl: HTMLInputElement | null;
let greetMsgEl: HTMLElement | null;

async function greet() {
    if (greetMsgEl && greetInputEl) {
        // Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
        greetMsgEl.textContent = await invoke("greet", {
            name: greetInputEl.value,
        });
    }
}

let count = 0;
listen<number>('test', () => {
    count++;
    if (greetMsgEl && greetInputEl) {
        greetMsgEl.textContent = `${count}`;
    }
});

window.addEventListener("DOMContentLoaded", () => {
    greetInputEl = document.querySelector("#greet-input");
    greetMsgEl = document.querySelector("#greet-msg");
    document.querySelector("#greet-form")?.addEventListener("submit", (e) => {
        e.preventDefault();
        greet();
    });
});

3. Build and run

pnpm tauri build
src-tauri/target/release/tauri-app.exe

4. Observe the memory usage in Task Manager, wait for the counter to reach 2 million

  • Frontend memory usage 1.1GB
  • Backend memory usage 120MB

Image

Expected behavior

The memory usage should remain relatively stable regardless of the number of events emitted

Full tauri info output

[✔] Environment
    - OS: Windows 10.0.26100 x86_64 (X64)
    ✔ WebView2: 133.0.3065.69
    ✔ MSVC: Visual Studio Community 2022
    ✔ rustc: 1.84.1 (e71f9a9a9 2025-01-27)
    ✔ cargo: 1.84.1 (66221abde 2024-11-19)
    ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
    ✔ Rust toolchain: stable-x86_64-pc-windows-msvc (default)
    - node: 22.13.1
    - pnpm: 9.15.5
    - npm: 10.9.2
    - deno: deno 2.1.10

[-] Packages
    - tauri 🦀: 2.2.5
    - tauri-build 🦀: 2.0.5
    - wry 🦀: 0.48.1
    - tao 🦀: 0.31.1
    - @tauri-apps/api : 2.2.0
    - @tauri-apps/cli : 2.2.7

[-] Plugins
    - tauri-plugin-opener 🦀: 2.2.5
    - @tauri-apps/plugin-opener : 2.2.5

[-] App
    - build-type: bundle
    - CSP: unset
    - frontendDist: ../dist
    - devUrl: http://localhost:1420/
    - bundler: Vite

Stack trace


Additional context

This memory leak issue appears to be related to wry.
I've created a related issue tauri-apps/wry#1489 that demonstrates similar memory leak behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs triage This issue needs to triage, applied to new issues type: bug
Projects
None yet
Development

No branches or pull requests

1 participant