PDA

View Full Version : [FIXED] [4.2.0.179] Memory Leak in Ext.form.field.Time



wsi
25 Nov 2013, 1:24 PM
REQUIRED INFORMATION
Ext version tested:


Ext 4.2.0.179
Browser:

Chrome 31.0.1650.57 m
Description:

Memory leak in Ext.form.field.Time
Steps to reproduce the problem:

Create and destroy a time field repeatedly.
The result that was expected:

No growth in memory
The result that occurs instead:

Growth in memory until the page crashes.
This may be due in part to a store being created in Ext.picker.Time's initComponent function. However, explicitly destroying that store only alleviates the memory growth; it does not stop it.
Two objects that seem to grow indefinitely are shown in the code below:
Test Case:


var timeField;
var repeater = function () {
if( timeField != null ) {
timeField.destroy();
timeField = null;
console.log( "Empty store listeners: " + Ext.StoreManager.map[ "ext-empty-store" ].events.beforeload.listeners.length );
console.log( "ModelManager types: " + Ext.Object.getSize( Ext.ModelManager.types ) );
}
else {
timeField = Ext.create( "Ext.form.field.Time", {
fieldLabel: "Time",
renderTo: Ext.getBody()
});
}
Ext.defer( repeater, 500 );
}

repeater();

Gary Schlosberg
26 Nov 2013, 7:30 AM
Thanks for the report! We have opened a bug in our bug tracker.

wsi
26 Nov 2013, 2:38 PM
Two overrides that seem to fix the problem. Code changes in red. Added comments in green.


Ext.override( Ext.picker.Time, {
initComponent: function() {
//When creating a time field, ext-empty-store is bound in the combobox creation.
//Then when a time picker is created, the listeners assigned in the ext-empty-store bind are
//not removed. Therefore we need to remove them here before we replace the store.
if( me.store ) {
me.store.clearListeners();
}
//Call Ext.picker.Time's actual initComponent
me.callParent();
},
});


Ext.override( Ext.form.field.ComboBox, {
onUnbindStore: function( store ) {
var picker = this.picker;
//There was previously a check for ( !store && picker ) but the store should always be unbound.
if (picker) {
picker.bindStore(null);
}
//Comboboxes create stores that use ImplicitModels for its store.
//These implicit models get added to all these places managers, so
//they need to be removed.
if( store ) {
if( store.model ) {
var modelName = store.model.getName();
if( typeof modelName == "string" ) {
delete Ext.data.Store[ modelName.substring( 15 ) ];
delete Ext.ModelManager.types[ modelName ];
delete Ext.ClassManager.classes[ modelName ];
}
}
}
this.clearFilter();
}
});

Edit: Made the combobox override safer with checks on the store's existence and simplified the time picker override.