简体   繁体   中英

Responsibilities of model creator regarding destroy in UI5?

What are the responsibilities of the developer to destroy / cleanup models previously created and set on a Control?

Given the following init code:

var oModel = new sap.ui.model.json.JSONModel();
var oData = new SomeData();
oModel.setData(oData);
this.setModel(oModel);

...what are the responsibilities of the developer on exit? Looking around the code I'm not seeing a definitive answer. Some code does nothing, some does the following in exit:

var oModel = this.getModel();
this.setModel(null);
oModel.destroy();

Which is correct? Is it the responsibility of the developer to unset the model and destroy it? Or does the UI5 framework take care of that like it does aggregations and the like? Since getModel can return the first model defined in the parent hierarchy must safeguards be taken to ensure that a destroy is not accidentally done on a model that others may be using?

According to documentation 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.

Is the only time models are automatically destroyed (and, as MessageProcessors, unregistered from the MessageManager) on app exit? Doesn't that lead to the possibility of many models hanging around taking up memory and having to be sifted through when it comes to firing model change events in the meantime?

Is it advisable / safe to destroy models in the exit of Controls rather than waiting for app exit so that it doesn't hang around and lead to an ever-growing memory footprint?

The Component destroys what it creates: The models defined in the component metadata (see OpenUI5 sources ).

The UIComponent also destroys the router and the created views ( sources ). The corresponding controller attaches its own onExit() method to the views beforeExit event . So everything you create in your Controller that should be cleaned up should be cleaned up there.

The interesting question is now: Is it sufficient to let the garbage collection do its job to destroy models that are not any more? And does destroying the view and deleting its controller really remove all references to the local models? Or is there a cache somewhere?

A short look at the code suggests that there is indeed a global cache: all Models inherit from sap.ui.core.message.MessageProcessor . In its destroy method deregisters it from the Cores MessageManager...


I have done a small experiment: I've created a simple test page that creates a large model in onInit() of a view. In one run it does call model.destroy() in onExit() of the view. In a second run it does not call 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>

The following screenshot shows the results: In onInit() about 140 MB is allocated on the heap. In the first run, the model is not explicitly destroyed. After destroying the view and enforcing a garbage collection (a feature of Chromes Timeline) only a few MB are freed. Probably the memory needed by the view itself.

In the second run model.destroy() is called in onExit() of the view. The allocated memory is freed completely at the forced garbage collection.

Chrome 时间轴中的 JS 堆

This hardenes my assumption, that you have to explicitly destroy the models you are creating your self.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM