模型创建者关于 UI5 中销毁的责任?
Responsibilities of model creator regarding destroy in UI5?
开发人员有什么责任销毁/清理以前在控件上创建和设置的模型?
给定以下初始化代码:
var oModel = new sap.ui.model.json.JSONModel();
var oData = new SomeData();
oModel.setData(oData);
this.setModel(oModel);
...开发人员退出时的责任是什么?环顾代码,我没有看到明确的答案。有些代码什么都不做,有些在退出时执行以下操作:
var oModel = this.getModel();
this.setModel(null);
oModel.destroy();
哪个是正确的?取消设置模型并销毁它是开发人员的责任吗?还是 UI5 框架会像处理聚合等那样处理这些问题?由于 getModel 可以 return 在父层次结构中定义的第一个模型必须采取保护措施以确保不会意外地对其他人可能正在使用的模型进行销毁?
根据文档here:
When a user closes the app, the destroy function of the component is
called. All models and the router are destroyed. The router will take
care of destroying the views.
是唯一一次模型在应用程序退出时被自动销毁(并且,作为 MessageProcessor,从 MessageManager 中注销)吗?这是否会导致许多模型占用内存并且在同时触发模型更改事件时必须进行筛选的可能性?
在控件退出时销毁模型而不是等待应用程序退出是否明智/安全,这样它就不会闲逛并导致不断增长的内存占用?
组件会破坏其创建的内容:组件元数据中定义的模型(请参阅 OpenUI5 sources)。
UIComponent 还会破坏路由器和创建的视图(sources). The corresponding controller attaches its own onExit()
method to the views beforeExit event。因此,您在 Controller 中创建的所有应该清理的东西都应该在那里清理。
现在有趣的问题是:让垃圾收集完成其工作以销毁不再存在的模型是否足够?销毁视图并删除其控制器是否真的删除了对本地模型的所有引用?还是某处有缓存?
简单看一下代码表明确实有一个全局缓存:所有模型 inherit from sap.ui.core.message.MessageProcessor. In its destroy 方法从 Cores MessageManager 中注销它...
我做了一个小实验:我创建了一个简单的测试页面,该页面在视图的 onInit()
中创建了一个大模型。在一个 运行 中,它确实在视图的 onExit()
中调用了 model.destroy()
。在一秒钟内 运行 它 不 调用 model.destroy()
.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-theme="sap_bluecrystal" data-sap-ui-libs="sap.m"></script>
<script type="sapui5/xmlview" id="view1">
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="view1">
<Button text="close view" press=".closeView" />
</mvc:View>
</script>
</head>
<body id="body">
<script>
sap.ui.core.mvc.Controller.extend("view1",{
onInit:function(){
var data = [];
for(var i = 0; i<1000000; i++){
data.push({text: "Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla"+i});
}
this.getView().setModel(new sap.ui.model.json.JSONModel(data));
},
onExit:function(){
this.getView().getModel().destroy();
},
closeView:function(){
this.getView().destroy();
}
});
var view = sap.ui.xmlview({viewContent: $("#view1").html()}).placeAt("body");
</script>
</body>
</html>
下面的截图显示了结果:
在 onInit()
中,堆上分配了大约 140 MB。在第一个 运行 中,模型没有被明确销毁。在销毁视图并执行垃圾回收(Chromes Timeline 的一项功能)后,只有几 MB 被释放。可能是视图本身需要的内存。
在视图的 onExit()
中调用了第二个 运行 model.destroy()
。分配的内存在强制垃圾回收时完全释放。
这强化了我的假设,即您必须明确地销毁您正在创建的模型。
开发人员有什么责任销毁/清理以前在控件上创建和设置的模型?
给定以下初始化代码:
var oModel = new sap.ui.model.json.JSONModel();
var oData = new SomeData();
oModel.setData(oData);
this.setModel(oModel);
...开发人员退出时的责任是什么?环顾代码,我没有看到明确的答案。有些代码什么都不做,有些在退出时执行以下操作:
var oModel = this.getModel();
this.setModel(null);
oModel.destroy();
哪个是正确的?取消设置模型并销毁它是开发人员的责任吗?还是 UI5 框架会像处理聚合等那样处理这些问题?由于 getModel 可以 return 在父层次结构中定义的第一个模型必须采取保护措施以确保不会意外地对其他人可能正在使用的模型进行销毁?
根据文档here:
When a user closes the app, the destroy function of the component is called. All models and the router are destroyed. The router will take care of destroying the views.
是唯一一次模型在应用程序退出时被自动销毁(并且,作为 MessageProcessor,从 MessageManager 中注销)吗?这是否会导致许多模型占用内存并且在同时触发模型更改事件时必须进行筛选的可能性?
在控件退出时销毁模型而不是等待应用程序退出是否明智/安全,这样它就不会闲逛并导致不断增长的内存占用?
组件会破坏其创建的内容:组件元数据中定义的模型(请参阅 OpenUI5 sources)。
UIComponent 还会破坏路由器和创建的视图(sources). The corresponding controller attaches its own onExit()
method to the views beforeExit event。因此,您在 Controller 中创建的所有应该清理的东西都应该在那里清理。
现在有趣的问题是:让垃圾收集完成其工作以销毁不再存在的模型是否足够?销毁视图并删除其控制器是否真的删除了对本地模型的所有引用?还是某处有缓存?
简单看一下代码表明确实有一个全局缓存:所有模型 inherit from sap.ui.core.message.MessageProcessor. In its destroy 方法从 Cores MessageManager 中注销它...
我做了一个小实验:我创建了一个简单的测试页面,该页面在视图的 onInit()
中创建了一个大模型。在一个 运行 中,它确实在视图的 onExit()
中调用了 model.destroy()
。在一秒钟内 运行 它 不 调用 model.destroy()
.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-theme="sap_bluecrystal" data-sap-ui-libs="sap.m"></script>
<script type="sapui5/xmlview" id="view1">
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="view1">
<Button text="close view" press=".closeView" />
</mvc:View>
</script>
</head>
<body id="body">
<script>
sap.ui.core.mvc.Controller.extend("view1",{
onInit:function(){
var data = [];
for(var i = 0; i<1000000; i++){
data.push({text: "Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla"+i});
}
this.getView().setModel(new sap.ui.model.json.JSONModel(data));
},
onExit:function(){
this.getView().getModel().destroy();
},
closeView:function(){
this.getView().destroy();
}
});
var view = sap.ui.xmlview({viewContent: $("#view1").html()}).placeAt("body");
</script>
</body>
</html>
下面的截图显示了结果:
在 onInit()
中,堆上分配了大约 140 MB。在第一个 运行 中,模型没有被明确销毁。在销毁视图并执行垃圾回收(Chromes Timeline 的一项功能)后,只有几 MB 被释放。可能是视图本身需要的内存。
在视图的 onExit()
中调用了第二个 运行 model.destroy()
。分配的内存在强制垃圾回收时完全释放。
这强化了我的假设,即您必须明确地销毁您正在创建的模型。