确认。使用OpenLayers,我有一个Ext.form.ComboBox,它运行Ext.data.JsonStore的查询来访问~1 Gb的shapefile并返回结果表。然后,用户可以选择其中一个结果,并将地图缩放到该位置。
这很好用。但!使用ComboBox时,JVM大小会持续增长 - 内存泄漏? - Geoserver会抛出许多与以下内容相关的问题:
Caused by: java.io.IOException: Map failed
Caused by: java.lang.OutOfMemoryError: Map failed
ERROR [geotools.map] - Call MapContent dispose() to prevent memory leaks
我可以在大约一分钟之内运行ComboBox多达五次,然后一阵错误让Geoserver崩溃(例如,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
代码:
THE QUERY:查找ComboBox&中键入的内容填充商店
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();
}
}
},
});
})
THE STORE
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"
}
});
ComboBox
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();
}
}
});
答案 0 :(得分:0)
这个解决方案有点模糊。我最终通过确保所有组合框存储的总大小加上初始Java -Xms分配不超过Java -Xmx分配来防止内存不足错误。
例如,将-Xms设置为500m,并且知道存储#1访问600m的数据库而存储#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或其他查询或ComboBox值直接传递给SQL或PostGIS数据库,并将javascript保留在其中。但我还不知道怎么写。