项目上使用CEF加载web服务。Cesium是开源GIS引擎,可以加载大面积的航拍模型,格式为3dTiles。
最近由于模型较大,发现一个问题:运行程序,什么都不操作,内存会不停上涨,直到耗尽所有系统内存。现象如下
用抓包工具捕获一下网络请求,发现都是在加载tile块。
找了好多资料,基本推断可能是两个方向发生了问题。一个是模型有问题,tile分块太多,另一个是CEF渲染模型时候发生异常,导致内存泄漏(类似这样的问题CEF Forum上有人反馈过,不过没找到解决办法)。所以优先从模型入手,因为用浏览器加载也会有内存上涨的问题,可见很大概率不是处理CEF出的问题。
由于模型比较大,重新处理比较麻烦,费时费力。所以打算用原生的Cesium API加载模型做测试,看是否是因为中间封装调用出的问题。
var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
// id: getCurrentTime(),
url: urlPath,
//maximumScreenSpaceError: isMobile.any() ? 8 : 1, // Temporary workaround for low memory mobile devices - Increase maximum error to 8.
//maximumNumberOfLoadedTiles: isMobile.any() ? 10 : 1000, // Temporary workaround for low memory mobile devices - Decrease (disable) tile cache.
}));
发现内存神奇的不再上涨。之前试过禁用CEF写入本地缓存,禁用GPU硬件加速等都无效,一次偶然的尝试,尽然找到问题的根源了。真实BUG虐我千百遍,我却待它如初恋。
上面注掉的两个参数正是导致内存不停上涨的原因:
maximumScreenSpaceError: isMobile.any() ? 8 : 1,
maximumNumberOfLoadedTiles: isMobile.any() ? 10 : 1000,
尤其最后一个参数,用来设定单次加载tile块的数量,当模型很小的时候不会有什么问题,当模型大到一定量级,并且tile分块较多的时候,就发生内存不停上涨的原因。
这种写法的另一个好处是,当初为了解决在移动端设备上加载服务,由于处理能力有限,对于加载数量做了限制。
至此,这个问题就解决了,内存确实不再上涨了。多提一句,tile分块较多的问题,西部世界提出了解决办法,合并块,也是为了解决分块多,马赛克加载的问题。