Memory leaks OpenLayers Ext.form.ComboBox存储查询创建内存泄漏
阿克。使用OpenLayers,我有一个Ext.form.ComboBox,它运行Ext.data.JsonStore的查询,以访问约1GB的shapefile并返回结果表。然后,用户可以选择其中一个结果,地图将缩放到该位置 这个很好用。但是随着组合框的使用,JVM的大小继续增长—内存泄漏—Geoserver引发了许多问题,这些问题主要与以下方面有关:Memory leaks OpenLayers Ext.form.ComboBox存储查询创建内存泄漏,memory-leaks,combobox,openlayers,geoserver,jsonstore,Memory Leaks,Combobox,Openlayers,Geoserver,Jsonstore,阿克。使用OpenLayers,我有一个Ext.form.ComboBox,它运行Ext.data.JsonStore的查询,以访问约1GB的shapefile并返回结果表。然后,用户可以选择其中一个结果,地图将缩放到该位置 这个很好用。但是随着组合框的使用,JVM的大小继续增长—内存泄漏—Geoserver引发了许多问题,这些问题主要与以下方面有关: Caused by: java.io.IOException: Map failed Caused by: java.lang.OutOfMem
Caused by: java.io.IOException: Map failed
Caused by: java.lang.OutOfMemoryError: Map failed
ERROR [geotools.map] - Call MapContent dispose() to prevent memory leaks
在Geoserver出现大量错误之前,我可以在大约一分钟内运行ComboBox多达五次(例如GetFeatureInfo不返回任何结果,ComboBox查询返回为空,显示粉色平铺,编辑:GWC停止制作新平铺!)
我需要销毁()或清理商店还是。。。?怎么做?想法
GeoExt 1.1、OpenLayers 2.12.rc6、Ext 3.4、Ext 4.2.1.883、jquery-1.6、Geoserver 2.5、JDK i586 v7、Tomcat 7
代码:
查询:查找组合框中键入的内容并填充存储
Ext.onReady(function() {
Ext.override(Ext.form.ComboBox, {
doQuery: function(q, forceAll) {
console.log('queryTpl', this.queryTpl, q);
q = Ext.isEmpty(q) ? '' : q;
var qe = {
query: q,
forceAll: forceAll,
combo: this,
cancel: false
};
if (this.fireEvent('beforequery', qe) === false || qe.cancel) {
return false;
}
q = qe.query;
forceAll = qe.forceAll;
if (forceAll === true || (q.length >= this.minChars)) {
if (this.lastQuery !== q) {
this.lastQuery = q;
if (this.mode == 'local') {
this.selectedIndex = -1;
if (forceAll) {
this.store.clearFilter();
} else {
this.store.filter(this.displayField, q);
}
this.onLoad();
} else {
this.store.baseParams[this.queryParam] = this.queryTpl ? String.format(this.queryTpl, q) : q;
this.store.load({
params: this.getParams(q)
});
this.expand();
}
} else {
this.selectedIndex = -1;
this.onLoad();
}
}
},
});
})
商店
var dsm = new Ext.data.JsonStore({
remoteFilter: true,
autoLoad: false,
autoDestroy: true, // doesn't appear to help
url: '../geoserver/workspace', // generalized, not for public access
storeId: 'myStore2',
baseParams: {
service: 'WFS',
version: '1.1.0',
request: 'GetFeature',
typeName: 'MRDS_LUT', // *shp in geoserver defined by var
srsName: 'EPSG:4326',
outputFormat: 'json',
propertyName: 'SiteName,Municipal,Commodity,Status,Longitude,Latitude'
},
root: 'features',
fields: [{
name: 'SiteName',
mapping: 'properties.SiteName'
}, {
name: 'Municipal',
mapping: 'properties.Municipal'
}, {
name: 'Commodity',
mapping: 'properties.Commodity'
}, {
name: 'Status',
mapping: 'properties.Status'
}, {
name: 'Longitude',
mapping: 'properties.Longitude'
}, {
name: 'Latitude',
mapping: 'properties.Latitude'
},{
name: 'bbox',
mapping: 'properties.bbox'
}],
sortInfo: {
field: "Municipal",
direction: "ASC"
}
});
组合框
var panelSiteNameSearch = new Ext.form.ComboBox({
store: dsm,
fieldLabel: "<b>Search</b>",
queryParam: "cql_filter",
queryTpl: "SiteName Like '{0}%'",
minChars: 5,
displayField: "SiteName",
valueField: "SiteName",
typeAhead: false,
loadingText: "Searching...",
width: 230,
emptyText: "Mine/Mineral Site Search",
hideTrigger: true,
tpl: '<tpl for="."><div class="search-item"><b>Site Name:</b> {SiteName}<br><b>Commodity: </b> {Commodity}<br><b>Municipality:</b> {Municipal}<br><b>Status:</b> {Status}</div><hr/></tpl>',
itemSelector: "div.search-item",
listeners: {
"select": function (combo, record) {
mrdsprimary.setVisibility(true);
mrdssecondary.setVisibility(true);
mrdstertiary.setVisibility(true);
map.setCenter(new OpenLayers.LonLat(record.data.Longitude,record.data.Latitude),13);
},
"focus": function () {
keyboardnav.deactivate();
},
"blur": function () {
keyboardnav.activate();
}
}
});
var panelSiteNameSearch=new Ext.form.ComboBox({
门店:帝斯曼,
字段标签:“搜索”,
queryParam:“cql_过滤器”,
queryTpl:“类似于{0}%'的站点名”,
明查斯:5,
显示字段:“站点名称”,
valueField:“站点名称”,
typeAhead:false,
loadingText:“正在搜索…”,
宽度:230,
emptyText:“矿山/矿场搜索”,
希德崔格:没错,
tpl:'站点名称:{SiteName}
商品:{Commodity}
市政:{civility}
状态:{Status}
,
项目选择器:“div.search-item”,
听众:{
“选择”:功能(组合、记录){
mrdsprimary.setVisibility(true);
mrdssecondary.setVisibility(真);
mrdsteritary.setVisibility(true);
setCenter(新的OpenLayers.LonLat(记录.数据.经度,记录.数据.纬度),13);
},
“焦点”:函数(){
键盘导航。停用();
},
“模糊”:函数(){
键盘导航激活();
}
}
});
这个解决方案有点模糊。通过确保所有组合框存储的总大小加上初始的Java-Xms分配不超过Java-Xmx分配,我最终防止了内存不足错误
例如,将-Xms设置为500m,并且知道store#1访问一个600m的数据库,store#2访问一个800m的数据库,那么在我的Java环境堆中总共会有1900mb。如果-Xmx设置为2g,则不会抛出错误
理论上。我不能直接影响Java环境的Xms而不干扰Tomcat/Java的本机GC。知道有总分配的Xmx上限,以及对它有直接影响的因素,会鼓励极度精简数据存储
不幸的是,我被限制在32位JDK i586上,我在某处读到它带有-Xmx固有的2gb限制(这似乎是正确的)。据报道,64位要高得多
发现:远程存储“加载”整个数据存储,并在本地提交筛选结果。。。使用removeAll或clearFilter或setValue()或NULL和/或SYNC清除存储只在本地起作用,实际上不会触发任何远程GC或减少远程Java的不必要存储堆
长期解决方案:创建一个服务器端PHP脚本,将给定的cql或其他查询或组合框值直接传递到SQL或PostGIS数据库,而不使用javascript。但我还不知道如何编写它。我添加了panelSiteNameSearch.store.removeAll();就在map.setCenter之后,我现在可以继续查询存储,无论JVM大小如何,ComboBox都可以正常工作,但是所有GetFeatureInfo和任何使用GeoWebCache的层仍然完全停止工作