热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用Instruments进行性能探查

在对企业做技术支持服务的过程中,我们经历过许多iOS项目。在每一个iOS开发过程中,开发者们总会遇见,一边运行游戏一边纳闷“这玩意儿为什么

在对企业做技术支持服务的过程中,我们经历过许多iOS项目。在每一个iOS开发过程中,开发者们总会遇见,一边运行游戏一边纳闷“这玩意儿为什么跑这么慢?”的时刻。其实有许多很不错的性能分析工具集,今天我们将会为大家介绍Instruments,这就是其中的佼佼者。
要使用Instruments,或任何其他的XCode调试工具,您必须构建一个以iOS为目标的Unity项目(同时取消对Development Build以及Script Debugging选项的勾选)。然后使用XCode以Release模式,将生成的XCode项目编译后发布到一个已连接的iOS设备上。
启动Instruments后(通过长按Play按钮,或选择 Products>Profile),选择Time Profiler。接着选择生成应用,并按下红色的Record按钮,便可启动探查过程。此时,iOS设备上会开始运行已连接了Instruments的应用,而Time Profiler则开始自动记录远程传回的信息。回传信息在Instruments的时间线上以蓝色折线图表示。

 

P.S.  Call Tree窗口右侧Details面板上的Settings子菜单中有Flatten Recursion 以及Hide System Libraries两个选项,可用于调整Call Tree窗口中调用的显示层次。
Instruments窗口中的详细区域会列出一系列方法调用,它们中的每个最顶级方法调用都代表了应用中的一个线程。
通常来说,因为main方法里包含所有托管代码,所以它成了理所当然的万众焦点。
展开main方法后,会出现一个非常庞大的方法调用树,其主要的分支会是以下两者之一:

  • [startUnity] 以及UnityLoadApplication(这些方法名有时会全大写显示)。
  • PlayerLoop

[startUnity]因为包含了初始化Unity引擎所需的所有时间,所以值得留意。在它下面是一个名为UnityLoadApplication的方法,在此方法之后方可进行启动时间探查。

 

当您对应用进行了一段时间的探查后,暂停Profiler,展开调用树。您会发现左栏以毫秒为单位的时间值沿树状结构向下递减。而您要做的是寻找那些上下差值巨大的时间点,即性能热点。随后您只要据此返回到对应代码,就可找到这时间黑洞的成因。
这原因有可能的确是某项必要的操作,也有可能是潜伏于您生产项目中的某些古老异类代码,或者……呃……原因真的是不胜枚举。怎样来(是否要)解决这个问题完全取决与您,因为没人比您更了解您的代码 :D。
Instruments还可以用于寻找分散的性能损耗点——即那些单独来说并没有造成很大时间消耗,但却在代码的许多不同位置不停吞噬少量时间的损耗点。
具体做法是,在Instruments中Call Tree窗口右上方的符号搜索框中输入部分或完全的函数名。如果正在探查的对象是一个游戏,则展开PlayerLoop并收起其下的其他方法。在某个特定操作上消耗的总毫秒数可以通过将PlayerLoop或UnityLoadApplication上所用的总时间减去self栏中对应的毫秒数进行粗略估计。
要查找的常见方法:
– “Box(“, “box” 以及 “box” — 这些代表了正发生C#值装箱操作;大多数的装箱实例都能轻易修正。

– “Concat” — 字符串连接操作通常可以很容易进行优化

– “CreateScriptingArray” — 所有返回数组的Unity API会分配数组的新副本。减少对这些方法的调用。

– “Reflection” — 反射(Reflection)很慢。用此来预估在反射上的时间损失,并尽可能去掉它。

– “FindObjectOfType” — 用此来定位重复的或非必要的FindObjectOfType调用,或其他已知超慢的Unity API。
– “Linq” — 根据时间损耗来确定创建或移除Linq查询;建议将热点对象替换为手工优化的方法。
Instruments除了能进行CPU时间探查之外,还可以用于探查内存使用率。Instruments的Allocations探查器提供了两个可以显示应用程序详细内存使用率的探针。Allocations探针能对特定时间段内驻留于内存中的对象进行检查。VM Tracker探针可对脏内存堆大小进行监视。脏内存堆是iOS确定是否要强制关闭一个应用的主要依据。
当在Instruments中选择Allocations探查器时,这两个探针都会同时运行。同样的,按红色的Record按钮开始探查过程。
要正确设置Allocations探针,必须确保Instruments右边Detail选项卡上的以下这些设定都正确。确保Display Settings (中间选项)下的Allocation Lifespan被设为Created & Persistent。确保Record Settings (左侧选项)已勾选 Discard events for freed memory 选项。
Allocations探针的默认视图Statistics是内存行为诊断的最佳利器。它显示为一条时间线。当使用推荐设置时,图表上会实时显示代表时间及内存分配程度的蓝色线条。通过这个图表,您可以仅通过简单重复测试场景,监控长时间占用或泄露的内存,并确保每次运行之间没有蓝线产生。
Call Tree是另一个有用的视图,它可以显示发生内存分配操作的代码行,以及该代码行所负责的内存量。
您可以看到下图中大约25%的内存使用量由着色器消耗。既然这些着色器都位于加载线程中,那它们必定是在应用启动时就加载的Unity项目捆绑的标准着色器。
从下图您可以看到,单单着色器就消耗掉了测试应用总内存使用量的25%左右。既然这些着色器都位于启动加载的线程中,那它们必定是在每次应用启动时就加载的,与默认Unity项目捆绑的标准着色器。

与前面一样,当您定位到热点位置时,后续的动作完全取决于您的项目本身。
好了,这就是一个Instruments简要介绍。


推荐阅读
  • C++ 异步编程中获取线程执行结果的方法与技巧及其在前端开发中的应用探讨
    本文探讨了C++异步编程中获取线程执行结果的方法与技巧,并深入分析了这些技术在前端开发中的应用。通过对比不同的异步编程模型,本文详细介绍了如何高效地处理多线程任务,确保程序的稳定性和性能。同时,文章还结合实际案例,展示了这些方法在前端异步编程中的具体实现和优化策略。 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • 近期,微信公众平台上的HTML5游戏引起了广泛讨论,预示着HTML5游戏将迎来新的发展机遇。磊友科技的赵霏,作为一名HTML5技术的倡导者,分享了他在微信平台上开发HTML5游戏的经验和见解。 ... [详细]
  • Flutter 2.* 路由管理详解
    本文详细介绍了 Flutter 2.* 中的路由管理机制,包括路由的基本概念、MaterialPageRoute 的使用、Navigator 的操作方法、路由传值、命名路由及其注册、路由钩子等。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 在《Cocos2d-x学习笔记:基础概念解析与内存管理机制深入探讨》中,详细介绍了Cocos2d-x的基础概念,并深入分析了其内存管理机制。特别是针对Boost库引入的智能指针管理方法进行了详细的讲解,例如在处理鱼的运动过程中,可以通过编写自定义函数来动态计算角度变化,利用CallFunc回调机制实现高效的游戏逻辑控制。此外,文章还探讨了如何通过智能指针优化资源管理和避免内存泄漏,为开发者提供了实用的编程技巧和最佳实践。 ... [详细]
  • 在处理大规模数据数组时,优化分页组件对于提高页面加载速度和用户体验至关重要。本文探讨了如何通过高效的分页策略,减少数据渲染的负担,提升应用性能。具体方法包括懒加载、虚拟滚动和数据预取等技术,这些技术能够显著降低内存占用和提升响应速度。通过实际案例分析,展示了这些优化措施的有效性和可行性。 ... [详细]
  • 在C#编程中,数值结果的格式化展示是提高代码可读性和用户体验的重要手段。本文探讨了多种格式化方法和技巧,如使用格式说明符、自定义格式字符串等,以实现对数值结果的精确控制。通过实例演示,展示了如何灵活运用这些技术来满足不同的展示需求。 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 本文介绍了如何利用ObjectMapper实现JSON与JavaBean之间的高效转换。ObjectMapper是Jackson库的核心组件,能够便捷地将Java对象序列化为JSON格式,并支持从JSON、XML以及文件等多种数据源反序列化为Java对象。此外,还探讨了在实际应用中如何优化转换性能,以提升系统整体效率。 ... [详细]
  • 本文深入探讨了C#中的反射与特性功能。首先,介绍了反射的基本概念,即通过元数据(包括类的方法、属性和字段等)在运行时动态获取和操作程序信息的能力。此外,还详细解析了特性的使用方法及其在代码注解和元数据扩展中的重要作用,为开发者提供了丰富的编程技巧和实践指导。 ... [详细]
  • 今天我开始学习Flutter,并在Android Studio 3.5.3中创建了一个新的Flutter项目。然而,在首次尝试运行时遇到了问题,Gradle任务 `assembleDebug` 执行失败,退出状态码为1。经过初步排查,发现可能是由于依赖项配置不当或Gradle版本不兼容导致的。为了解决这个问题,我计划检查项目的 `build.gradle` 文件,确保所有依赖项和插件版本都符合要求,并尝试更新Gradle版本。此外,还将验证环境变量配置是否正确,以确保开发环境的稳定性。 ... [详细]
  • 探讨异步 Rust 中多线程代码无法实现并行化的原因及解决方案。 ... [详细]
  • com.sun.javadoc.PackageDoc.exceptions()方法的使用及代码示例 ... [详细]
author-avatar
hfy2409553
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有