大规模WebGL应用引发浏览器崩溃的几种情况及解决办法
Posted Graphing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大规模WebGL应用引发浏览器崩溃的几种情况及解决办法相关的知识,希望对你有一定的参考价值。
我们使用javascript写WebApp的时候,一般都不会考虑对象的生命周期,不太关注内存“泄露”的问题,依赖JS引擎的垃圾回收机制就可以运行的很好,基本上很少会出现浏览器崩溃的情况。但在Web端显示大规模三维模型的时候,内存/显存就是一个非常紧张的资源,需要综合考虑模型数据组织、任务调度、资源管理、浏览器兼容等方方面面的问题。本文针对我们在开发基于WebGL的三维应用中遇到到几种导致浏览器崩溃的情况进行分析并提供解决方案。
异步请求过多
浏览器对并发异步请求是有限制的。如果程序不做处理,“同时”发送几百个请求就可能导致浏览器崩溃。
解决办法:
使用请求队列:把需要多次请求得到的数据重新组织,在一次或几次请求完成。如果非得需要很多次(几百上千的情况)请求,可以把请求排队,用多个异步请求队列加载数据。
并发异步请求资源死锁
若一个资源被多个异步请求同时请求的时候就可能导致浏览器死锁,死锁的结果就是浏览器崩溃。默认浏览器都是启用cache的,而浏览器在从cache中读取数据的时候会加锁。
解决办法:
在组织异步请求队列的时候,把相同的资源放在相同的队列中,而不是放在不同的队列中。
GPU进程崩溃
Chrome是多进程架构,每个Tab都会启用单独的进程来处理页面。但所有的进程都会公用一个GPU进程。那么问题来了,如果开启多个WebGL应用页面,每个页面占用一定的GPU资源,GPU进程的内存加起来总的就会轻轻松松超过1.5G,结果就是GPU进程崩溃。使用64位Chrome情况会稍有改善,但依赖本机的GPU显存大小。在实际中用WebGL显示大模型会轻轻松松的撑爆GPU进程。
解决办法:
优化Mesh数据
Mesh简化
Mesh共享
使用对象池
限制同时绘制对象的数量
JS对象过多导致崩溃
在上图中的浏览器管理器中可以看到多个内存:内存、GPU内存、Javascript内存。其中Javascript内存是JS对象占用的内存,JS垃圾回收的是这部分内存。
Javascript代码和垃圾回收运行在同一个线程的环境,当垃圾回收的时候,js代码不会执行。如果js对象过多,(占用内存过多),垃圾回收的过程也会变得漫长。所以Chrome简单粗暴的限制了Javascript内存的占用,在x64下最大~1.4G。
解决办法:
优化数据结构
增加数据动态管理的机制。
JS代码运行超时
如果JS运行时间过长,超出一定的时间,浏览器就弹个对话框,让用户选择是否结束。相同的代码在chrome中没有问题,而在firefox中就可能无响应。
解决方法:
把耗时的算法设计成分步执行,使用requestAnimationFrame模拟多线程。
总结
相对桌面应用程序开发,浏览器是一个资源受限的环境:JS执行效率,内存,线程等。对于大规模的Web应用,我们经常需要在性能和资源上做平衡。
以上是关于大规模WebGL应用引发浏览器崩溃的几种情况及解决办法的主要内容,如果未能解决你的问题,请参考以下文章
总结遇到的elasticsearch启动失败的几种情况及解决