要了解几个概念:

  • ManagedHeap 表示的是Mono所使用的托管堆内存,C#上任何的申请托管的内存都会在这个上面申请。
  • ManagedHeap.UsedSize 表示这个托管堆上已经使用的内存大小
  • ManagedHeap.reservedUnUsedSize 表示托管堆上未使用的内存大小

当我们申请内存时,如果ManagedHeap.reservedUnUsedSize的内存不够用,Mono会向os申请内存。并且这个内存会扩大ManagedHeap的大小,并且这个内存不会回落。

我们可以通过Profiler.GetMonoHeapSize()获取Mono堆上的总内存和mono_gc_get_heap_size是一个意思。

下面写了一个测试用例:

  1. using UnityEngine;

  2. using System;

  3. using System.Runtime.InteropServices;

  4. using System.Text;

  5. public class TestManagedHeap : MonoBehaviour

  6. {

  7. public int arraysize = 1024 * 1024 * 200;//条件触发延迟申请的内存1

  8. public int arraysize_frame = 1024 * 1024 * 10;//条件触发延迟申请的内存2

  9. [DllImport("mono.dll")]

  10. public static extern long mono_gc_get_used_size();

  11. [DllImport("mono.dll")]

  12. public static extern long mono_gc_get_heap_size();

  13. //private StringBuilder builder = new StringBuilder(256);

  14. // Use this for initialization

  15. void Start()

  16. {

  17. }

  18. // Update is called once per frame

  19. void Update()

  20. {

  21. if (Input.GetKeyDown(KeyCode.U))

  22. {

  23. byte[] array = new byte[arraysize];

  24. array = null;

  25. Debug.Log("申请200M");

  26. printMemory();

  27. }

  28. if (Input.GetKeyDown(KeyCode.A))

  29. {

  30. byte[] array = new byte[arraysize_frame];

  31. Debug.Log("申请10M");

  32. printMemory();

  33. }

  34. if (Input.GetKeyDown(KeyCode.B))

  35. {

  36. Debug.Log("调用GC");

  37. GC.GetTotalMemory(true);

  38. printMemory();

  39. }

  40. }

  41. void printMemory()

  42. {

  43. long usedsize = mono_gc_get_used_size();

  44. long heapsize = mono_gc_get_heap_size();

  45. long reservedsize = heapsize - usedsize;

  46. builder.Length = 0;

  47. //builder.AppendFormat("使用内存:{0},剩余内存{1},托管堆内存{2}",usedsize,reservedsize,heapsize);

  48. //print(builder.ToString());

  49.     Debug.Log("使用内存=" + usedsize * 1.0f / 1024 / 1024 + "M");

  50.    Debug.Log("剩余内存=" + reservedsize * 1.0f / 1024 / 1024 + "M");

  51.     Debug.Log("托管堆内存=" + heapsize * 1.0f / 1024 / 1024 + "M");

  52.  }

在测试中会发现,当申请了200M的内存后,再申请10M的内存。堆上的内存mono_gc_get_heap_size并没有减少,这是因为,在Mono堆上的内存在应用程序运行期间是只增不减的,即使GC也不会把申请的内存还给os,而是设置成了未使用状态。

Memory is allocated in heap blocks. More can allocated if it cannot fit the data into the allocated block. Heap blocks will be kept in Mono until the app is closed. In other words, Mono does not release any memory used to the OS (Unity 3.x). Once you allocate a certain amount of memory, it is reserved for mono and not available for the OS. Even when you release it, it will become available internally for Mono only and not for the OS. The heap memory value in the Profiler will only increase, never decrease.

上面是摘自Unity官方API对Profiling对Mono Memory的解释。

鉴于这个原因,在app开发时需要注意什么呢?

  1. 不要一次性申请过大的内存;
  2. 切换场景等操作时可以自己手动调用GC.Collect

///

Unity内存优化 之 ManagedHeap 整理相关推荐

  1. Unity内存优化经验分享

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...

  2. Unity 内存优化之理解托管堆和本机堆

    https://docs.unity3d.com/Manual/BestPracticeUnderstandingPerformanceInUnity4-1.html https://www.dazh ...

  3. 【Unity】Unity内存管理与优化(一)内存域、堆栈、垃圾回收、内存泄漏、内存碎片

    文章目录 Unity内存 内存域 - 托管域 - 本地域 - 外部库 - 跨桥操作 堆和栈 - 栈 - 堆 - 堆栈的使用 垃圾回收 - Mono内存分配过程 - 内存泄漏 - 内存碎片 - 运行时垃 ...

  4. 【Unity】Unity内存管理与优化(三)

    文章目录 Unity内存管理 大对象堆LOH(Large Object Heap) 方法调用 内存细分 分析内存 - 分析内存消耗 - 分析内存效率 内存管理性能增强 垃圾回收策略 手动JIT编译 值 ...

  5. unity性能优化方案整理 一些思路 一些技巧(持续更新 2019-09-12)

    原文链接1:https://www.cnblogs.com/zhenlong/p/4862869.html 原文链接2:http://www.xuanyusong.com/archives/3205 ...

  6. Unity - 性能优化 - 包体,内存 - 偏静态资源的优化

    文章目录 静态资源优化 - AssetPostprocessor Texture 压缩 Model 网格.动画 压缩 音频压缩 纹理的优化经验 尺寸 通道 发布出来的包资源再次分析 如何工具快速定位静 ...

  7. Unity内存管理和GC优化

    目录 [性能优化]内存管理和GC优化 前言 内存优化思维导图 一.托管堆基础知识学习 1.1. Unity游戏运行时内存占用分以下几部分: 1.2 GC和堆内存联系 二.垃圾回收何时触发 三.GC如何 ...

  8. Unity UWA内存优化总结列表

    1.2 Unity性能优化进无止境之内存篇(基础篇) 谈优化必谈内存,该文深入浅出地分析了Unity项目的内存占用 内存开销无非三大块:资源内存占用,引擎模块内存占用,托管内存占用 Mipmap ,W ...

  9. 第一章:unity性能优化之内存优化

    目录 前言 unity性能优化之内存的优化 一.unity Analysis工具的使用. 二.内存优化方法 1.设置和压缩图片 2.图片格式 3.动画文件 4.模型 5.RenderTexture(R ...

最新文章

  1. HDU - 4027 Can you answer these queries?(线段树)
  2. java第三周学习总结
  3. Hive数据倾斜优化
  4. Page.ClientScript.RegisterStartupScript() 方法与Page.ClientScript.RegisterClientScriptBlock() 方法
  5. Java虚拟机(十)——直接内存概述
  6. 95后人才吸引力城市排名发布,深圳位居全国第二
  7. 苹果宣布取消AirPower 因技术难题无法攻克
  8. 在搜索框自动输入文本_selenium自动化测试之常见的定位元素
  9. 2021年提升效率的7个新vue实战技巧!
  10. python核心装饰_《python核心编程》中高级闭包和装饰器理解?
  11. 个人宏工作簿PERSONAL.XLSB 保存位置 启动加载项
  12. 9-11NOIP模拟赛总结
  13. syn-proxy源码分析(1)
  14. TabContainer样式设置(2)
  15. 快速比对源代码的工具_推荐7个代码对比工具
  16. python结课设计力学方面_课程设计心得
  17. 配置disney的brdf项目全过程
  18. C++快速入门学习笔记(一)
  19. linux风扇转速,ubuntu系统调节GPU风扇转速
  20. @html.dropdownlist默认多选,Html.DropDownList()赋默认值

热门文章

  1. 网络对抗技术 实验二
  2. 圆通快递拒收后,如何快速查询退回件单号的物流情况
  3. 2018滴滴校招(秋招)内推笔试编程题题解
  4. android蓝牙hid 鼠标,BLE HID协议-----蓝牙鼠标代码流分析
  5. 总结:Springboot的pom配置
  6. mongodb不等于某个值_mongodb条件查询不等于
  7. EntityFramework 的5种状态-简记
  8. apicloud 开发app 引用vue+element_ui的方法
  9. LaTeX的下载和使用(TexLive + TexStudio)
  10. ArcGIS API for JavaScript实现坐标定位