DioxusLabs / dioxus

Fullstack app framework for web, desktop, mobile, and more.
https://dioxuslabs.com
Apache License 2.0
20.32k stars 779 forks source link

bug: Potential memory leak (maybe just on native-core) #1361

Closed marc2332 closed 1 year ago

marc2332 commented 1 year ago

Problem

Removing X elements and adding them back should maintain the same memory usage, instead it always increases

Steps To Reproduce

Run this modified example: https://github.com/marc2332/dioxus/blob/memory-leak/packages/native-core/examples/memory-leak.rs

Expected behavior

Memory should not increase if the DOM size is the same.

Screenshots

https://github.com/DioxusLabs/dioxus/assets/38158676/c506e791-73fd-4f42-ab5f-22c75f578774

Environment:

ealmloff commented 1 year ago

This code leaks memory with just core:

#![allow(non_snake_case)]
use dioxus::prelude::*;
use std::sync::atomic::AtomicUsize;

fn main() {
    fn app(cx: Scope) -> Element {
        Some({
            let __cx = cx;
            static TEMPLATE: ::dioxus::core::Template = ::dioxus::core::Template {
                name: "examples/readme.rs:14:9:432",
                roots: &[::dioxus::core::TemplateNode::Dynamic { id: 0usize }],
                node_paths: &[&[0u8]],
                attr_paths: &[],
            };
            ::dioxus::core::VNode {
                parent: None,
                key: None,
                template: std::cell::Cell::new(TEMPLATE),
                root_ids: Default::default(),
                dynamic_nodes: __cx.bump().alloc([__cx.make_node("Testing")]),
                dynamic_attrs: __cx.bump().alloc([]),
            }
        })
    }

    let mut vdom = VirtualDom::new(app);

    let _ = vdom.rebuild();

    loop {
        // get the mutations from the vdom
        {
            let mutations = vdom.render_immediate();
            println!("Mutations: {:#?}", mutations);
        }
        vdom.mark_dirty(ScopeId(0));
        println!("{vdom:#?}");
    }
}