Задать вопрос
Trame2771
@Trame2771

Правда ли что wasm при пиковой нагрузке отожрав память, после спада нагрузки её не возвращает?

Я где-то читал, что если wasm модуль имеет процесс, для которого нужно аллоцировать памяти для wasm-а, то память, задействованная этим процессом не вернёться обратно на нужды браузера или операционки. В wasm-е есть возможность этим управлять? Или единственным способом будет отделять такой жрущий память процесс в отдельный модуль, а потом этот модуль удалять в runtime-е?

#[wasm_bindgen(start)]
pub fn js_main() -> Result<(), JsValue> {
    let window: web_sys::Window = web_sys::window().unwrap();
    let document: web_sys::Document = window.document().unwrap();
    let canvas: web_sys::Element = document.get_element_by_id("canvas").unwrap();

    console::log(&vec![&canvas, &200, &"Some text"]);
    
    webgl_context_obtain(&canvas);
    
    
    let mut a: Vec<i64> = [0; 29999999].to_vec();
    let mut i = 0i64; loop {
        a[i as usize] = i;
        
        i += 1;
        if i as usize == a.len() {break}
    }
    // for val in a {
         console::log(&vec![&"ok"]);
    // }
    
    Ok(())
}


После завершения программы:
(В консоли "ok")
6521f28f69ad3772505845.jpeg

После закрытия вкладки:
6521ed6d7a124499103362.jpeg

Я так же вынес создание и наполнение вектора в другую функцию, и вызвал эту функцию в главной. Тоже самое потребление

Так же проверил что будет если убрать операцию создания и наполнения вектора совсем, чтобы проверит не жрёт ли случайно wasm сам по себе ~350мб. Нет. Без нагрузки на память вкладка потребляет 50мб. УЖАС ВАЗМ НЕ ОПТИМИЗИРОВАН. Хотя не факт что всё так плохо, возможно память очищается когда совсем уж неадекватные потребления. Или просто приложение крашиться и память забирается... Афигенная спецификация у вазма... (Если это вообще вина спецификации)

Заменил
let mut a: Vec<i64> = [0; 29999999].to_vec();
на
let mut a: Vec<i64> = [0; 49999999].to_vec();
и всё крашнулось к чертям (браузер остановился, все приложения в фоне перезапустились). Браузер не возвращает память при острой необходимости, потому что прошлая попытка была близка к критическому потреблению, можно было бы тогда и отдать гигабайт памяти какой
  • Вопрос задан
  • 71 просмотр
Подписаться 1 Простой 13 комментариев
Пригласить эксперта
Ответы на вопрос 1
@argunov
Вы правы, память не освобождается!

Краткая история освобождения памяти васмом:
  1. на pre MVP этапе васм умел отдавать память в систему
  2. освобождение работало медленно, поэтому его посчитали небезопасным и выпилили из MVP (чтобы клиенты неосознанно не дёргали освобождение по поводу и без)
  3. периодически приходят люди и просят вернуть освобождение памяти в васм
  4. разрабы васма оттягивают этот момент, потому что это потребует или серьёзного редизайна или опять получится медленное решение. Проблема в том, что для освобождения памяти нужно провести её дефрагментацию. А без дефрагментации мы не можем освобождать даже свободные блоки, потому что в васме память линейная и блоки должны нумероваться по порядку и убрать из использования блок, который в середине памяти инстанса - нельзя, нужно менять модель памяти.

Ну и если кто-то захочет сам прикоснуться к истории:

Подход "пересоздавать инстанс, чтобы освободить память" - это общий подход, так приходится делать всем, кто хочет освобождать память
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы