Финализаторы для объектов JavaScript
Предположим, у меня есть некоторый код asm.js, вероятно, созданный emscripten. Предположим, что у него есть какая-то довольно большая выделенная структура кучи, которая возвращается функцией asm.js в качестве указателя, который выбирается какой-то библиотекой JavaScript для обертывания в красивый объект JavaScript. Хорошо пока.
Но что произойдет, если этот объект выйдет из области видимости и соберет мусор. В данный момент код asm.js не имеет возможности узнать об этом, поэтому память структуры останется выделенной, что приведет к утечке памяти.
Есть ли способ добавить финализатор к объекту JavaScript изнутри JavaScript?
Такой финализатор может быть использован для освобождения памяти в asm.js, что позволяет избежать утечки памяти. До сих пор я не мог найти документированный, то есть портативный способ добиться этого, но, возможно, я искал не в тех местах.
1 ответ
Простой ответ заключается в том, что это не поддерживается.
Поскольку код asm.js должен управлять своей собственной памятью, все, что взаимодействует с объектами, хранящимися на стороне asm, должно уважать менеджер памяти, который использует asm, а не менеджер памяти, который использует браузер. Лучшее, что вы можете сделать - это явно вызывать метод для любого объекта, ссылающегося на внутреннюю память asm, всякий раз, когда вы создаете или уничтожаете ссылку на него.
Возвращаясь к этому вопросу, я нашел другой ответ, в котором указывалось, что существует спецификация для слабых ссылок и финализации, которую реализуют некоторые браузеры. Центральный компонент для завершения - FinalizationRegistry.
Так что в зависимости от того, на какие браузеры вы нацеливаетесь, это может быть возможно сейчас. Если вам нужно поддерживать браузеры без этой функции, используя явные вызовы релиза, возможно, можно будет использовать финализаторы, если они поддерживаются, для обнаружения утечек памяти (т. Е. Объектов, явно не выпущенных в коде JavaScript), и сообщить разработчику, чтобы они могли это исправить.