- 1、本文档共7页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Unity WebGL内存详解:Unity堆
Unity WebGL内存详解一文对比了WebGL及其它平台内存的工作方式。我们给出的建议是Unity堆应越小越好,同时也强调了一个事实,即浏览器中还存在其他类型的内存开销。本文将深入探讨Unity堆,并根据实际数据来减少Unity堆的大小,而不再是通过不停地调试和试错来达到这一目的。下面就来看看Unity堆的定义、原理以及如何进行Unity堆内存分析。
Unity堆是什么
首先要明白,Unity堆和浏览器堆是不同的概念。Unity堆实际上只是浏览器堆中的一块内存。这方面的讲解可在 之前的WebGL内存详解中查看。大体上说,所谓堆就是一块用于动态分配的内存,允许应用程序使用malloc/free或new/delete对内存进行操作。Unity有自己的内存分配系统,以便提高内存的利用率,同时更加方便地进行分析与调试。但在底层仍然使用malloc/free。
在Unity WebGL中,将含有所有运行时Unity引擎对象的这块内存称为Unity堆。Unity堆中的内存分配是通过dlmalloc完成的。在主机平台上,这个堆的大小由硬件规格和操作系统保留内存的大小所决定,因此应用程序应保证其申请的内存不会超过运行时可用内存。在WebGL平台上同理,我们需要预先定义Unity堆的大小(即在应用程序构造时)。这就是说一旦初始化,Unity堆的大小就不会再发生变化。
Unity堆中有什么
在Unity WebGL平台中,将Unity堆分配类型分类如下:
静态内存区域
栈
动态内存
未分配内存
被分配的第一块区域用于栈和存放所有静态对象。栈的大小通常是5MB,而静态区域的大小取决于编译的代码,即通常受Unity和工程版本所影响。上面这些区域分配好之后,剩余的所有内存即可供运行时动态内存分配使用。当代码开始执行后,动态区域就会占据越来越多的Unity堆空间。如果这片区域占据的空间过多,最终就会导致没有内存可供Unity使用。
随着时间的推移,即便会有一些对象被释放或者其他对象的内存再分配,动态内存区的大小是不会减少的,因为没有对应的压缩机制。而且这类操作会使动态内存区产生碎片。
所以要知道,内存中是会有碎片产生的。
那托管内存哪去了?动态区域中有一个或多个运行时托管堆,程序创建的所有对象都在其中。因此,托管堆是Unity堆的一部分,而Unity堆又是浏览器JS VM堆的一部分。听起来可能有些复杂,如果看过《盗梦空间》或《黑客帝国》,那这里就好理解多了,一个堆在另一个堆中,另一个堆又在另外一个堆中,以此类推……
托管内存
所有脚本对象都存放于此。之所以叫它“托管”是因为每当一个对象不再被引用时,垃圾回收器(Boehm)就会自动回收这部分内存。首先需要了解的一个重点是:托管内存是从Unity堆中分配的?(或从其他平台上的操作系统分配)。其次,这部分内存不会再归还给操作系统,因此托管堆的大小只增不减。实际上,当一个对象被回收后,它原本占用的内存仍旧被保存在托管堆中以供将来使用。
就Unity WebGL而言,当我们说“内存不会被归还给操作系统”时,实际上说的是这部分内存不会再归还给Unity堆中的可用内存块池。还有一点需要强调的是,与Unity堆不同(Unity堆是单个一整块内存),Boehm垃圾回收器有分配多重缓存的能力。另外,每一块缓存都可以按需被分割为更小的块。不过当创建新的脚本对象时,需要一块足够容纳这个对象的毗邻内存空间,如果Boehm垃圾回收器托管的可用块不足以满足需求,则会创建一个新的内存块(从Unity堆中划取)。更多关于托管内存的信息,请查阅Unity手册。
1
托管内存用尽后会如何?
如果Boehm垃圾回收器没能找到用于创建新对象的空闲内存,则从Unity堆请求分配失败,Unity WebGL将停止执行,同时抛出内存不足的错误并建议增加WebGLMemorySize的大小。
2
System.GC.Collect无法用于WebGL吗?
Unity WebGL平台上调用GC.Collect()是没有效果的。因为调用栈在不为空的时候是无法进行垃圾回收操作的。更多有关该限制的内容可查阅Unity手册。这时,Unity WebGL会在每帧开始时尝试进行一些垃圾回收操作。之后在载入新场景时,系统会进行一次完全垃圾回收操作。
3
System.GC.GetTotalMemory具体做什么?
在Unity WebGL平台上,该函数的作用与在其他平台上比是相同的,同时也提供了垃圾回收异常机制:System.GC.GetTotalMemory()?返回当前使用的所有托管内存,正如Profiler.GetMonoUsedSize()一样。如需了解托管堆的总大小(已使用+空闲),可
您可能关注的文档
- PHOTOSHOP 打印CAD线型图 CAD线形图.doc
- Photoshop园林景观效果图制作 任务三:清新风格-某断面效果图制作 项目二任务三 清新风格剖断面效果图.docx
- PHP+MySQL网站开发技术 PHP获取WEB表单数 5-1php实例.docx
- PHP+MySQL网站开发技术 PHP面向对象程序设计 数组实例2.docx
- PLC技术及应用(三菱PLC) 选择性分支状态编程 《选择性分支状态编程》教学设计.doc
- PLC技术应用 课程标准 《PLC控制系统的运行与维护》课程标准.doc
- PLC技术应用 课程标准 《PLC应用技术》课程标准.doc
- PLC技术应用 人才培养方案 应用电子技术专业培养方案1.doc
- PLC控制系统设计与安装调试 5.2.1 移位指令 电子教材--移位指令.doc
- PLC控制系统运行与维护(西门子) STEP7和PLCSIM的初步认识 STEP7和PLCSIM的初步认识.doc
文档评论(0)