为什么自己编写的页面总是在那里抖动_「内存抖动」?别再吓唬面试者们了行吗...

视频版本

本文在 B 站有对应的视频,如果你喜欢看视频版本,可以点 这里 去哔哩哔哩观看,或者点 这里 去 YouTube 观看。

从「内存抖动」说起

面试官:你做过性能优化是吧。
面试者:嗯是的,在卡顿和耗电问题上做过挺多事。
面试官:内存抖动的解决方案你有了解过吗?
面试者:内存什么?
面试官:内存抖动。没有听过吗?
面试者:……没有。
面试官:呼(摇头)。年轻人还是要敬畏技术啊,要持续学习啊。
面试者:我……嗯……

大家好,我是扔物线朱凯。

看起来很酷的词总是容易吸引眼球,比如「双亲委托」,比如「责任链」,比如——「内存抖动」。吸引眼球就意味着会有更多点击,而点击量是内容创作者最爱的东西,所以这些名字很酷的词就很自然地会受到各种技术文章的偏爱,因为你写这些文章可以得到更多的流量,这是无可厚非的。强调一下,这是无可厚非的。但有些作者对于流量的追求过于偏执,什么东西都喜欢过分地吹一下。

133f5c54e635fcef12f39b23e4fa7712.png

大家作为读者,看文章的时候要有辨别力,不要被这些流量词带偏,更不要被某些流量贩子们骗得去加到自己的面试题里来考验你的面试者是否读过某篇文章,这是没有价值的。

有价值,还是没有?

啊啊?「内存抖动」这个概念竟然没价值?

不是的 ,我不是说内存抖动的概念没价值。哎算了,我先说一下什么是内存抖动吧:

在程序里,每创建一个对象,就会有一块内存分配给它;每分配一块内存,程序的可用内存也就少一块;当程序被占用的内存达到一定临界程度,GC 也就是垃圾回收器(Garbage Collector)就会出动,来释放掉一部分不再被使用的内存。Android 里的 View.onDraw() 方法在每次需要重绘的时候都会被调用,这就意味着,如果你在 onDraw() 里写了创建对象的代码,在界面频繁刷新的时候,你就也会频繁创建出一大批只被使用一次的对象,这就会导致内存占用的迅速攀升;然后很快,可能就会触发 GC 的回收动作,也就是这些被你创建出来的对象被 GC 回收掉。垃圾内存太多了就被清理掉,这是 Java 的工作机制,这不是问题。问题在于,频繁创建这些对象会造成内存不断地攀升,在刚回收了之后又迅速涨起来,那么紧接着就是又一次的回收,对吧?这么往复下来,最终导致一种循环,一种在短时间内反复地发生内存增长和回收的循环。

这种循环往复的状态就像是水波纹的颤动一样,它的专业称呼叫做 Memory Churn,Android 的官方文档里把它翻译做了内存抖动。所以内存抖动其实并不是我们的内存在整体地进行摇晃这样神奇的事情,

4e00e533e062167d40d0c5aadf187662.png

而仅仅是类似有一根搅拌棒轻轻地在内存的边界上进行搅动的样子——其实翻译成「内存搅动」好像也行哈?

我们也可以通过 Android Studio 的 Memory Profiler 来更直观地观察到这种现象:

585f930708870115c1c70492096b21cd.png

内存的回收虽然很快,时间成本很低,但终究是有时间成本的。一两次内存回收不容易被用户察觉,但多次内存回收行为集中在短时间内爆发,这就造成了比较大的界面卡顿的风险。这也是为什么 Android 在官方文档和 Android Studio 里都建议我们尽量避免在 onDraw() 里创建对象。

42e33418adca2eadcc488b4134aaee1e.png

同样的道理,不只是在 onDraw(),在次数比较大的循环里创建对象,同样会导致内存抖动。不过因为在实践中,我们在 onDraw() 里创建的对象往往是绘制相关的对象,而这些对象又经常会包含通往系统下层的 Native 对象的引用,这就导致在 onDraw() 里创建对象所导致的内存回收的耗时往往会更高,直白地说就是——界面更卡顿。

另外呢内存抖动有时候也会抖着抖着就变成内存溢出了,这就是更严重的情况,因为内存溢出的直接结果就是软件崩溃。

有价值,但「内存抖动」这几个字不是关键

所以,「内存抖动」这个概念有价值吗?

当然有价值了,因为这个词帮助我们很形象地去形容了程序中的一种现象。对吧?增加、回收、增加、回收。

那么我在开头说的「没价值」,指的是什么呢?

我说的不是「内存抖动」的概念没价值,而是追求对这个概念本身的了解是没价值的。确切地说是,面试官们企图用是否知道「内存抖动」这样的词来考察面试者是否具有高开发水平这样的面试策略,是没价值的。内存优化是一个很复杂很细碎的话题,而在 onDraw() 中避免创建对象只是其中的冰山一角。而且就算在这冰山一角里,重点也只在于「避免内存增长」,而不是「避免内存抖动」。内存抖动只是一种具体的表面现象而已,而这种现象背后的原因,除了在 onDraw() 中创建对象,也很少再有其他场景了。那么这种场景限定极强的词被专门列出来在面试题里,又有什么意义呢?

当我们问「内存抖动」,我们应该关心什么

我不是在说你面试的时候不应该问内存抖动,而是说你的注意力一定不能放在这个词上。听没听说过内存抖动并不重要,知道内存抖动的原因和解决方案才重要。

嗯……没听过内存抖动,怎么会知道它的原因和解决方案?

他没听过你可以告诉他呀!不是不能问内存抖动,而是如果你问了之后对方表示没听过,你应该进一步引导,比如你问他:那么,Android 官方建议我们不要在 onDraw() 里创建对象你知道吗?你知道为什么吗?如果他立即回答这会导致频繁触发内存回收,那不是证明他其实懂原理的吗?这时候你再告诉他,这就叫内存抖动,就行了。

而且也不要局限于这一个词,你还可以继续问:为什么在 onDraw() 里创建对象导致的结果是内存抖动而不是内存溢出?这种对于能力的考察比对词汇的考察重要多了。其实我也不是很确定这个问题是不是每个喜欢问内存抖动的面试官们都能回答上来,但这样问才是考察程序员能力的最好方式。

如果你在面试时问了内存抖动,但在对方表示没听过之后,你就不再进行任何的引导而是直接给对方扣了分,那你其实相当于在问:我这里有一个高端词汇,您听过吗?

自吹自擂

我在上课的时候,经常跟学员强调学技术要学本质,因为有些地方我讲得比较深我怕他们不学。说到我的课,有想学 Android 高级进阶系列化知识的,扫码咨询。

https://u.wechat.com/MDjgjMMWVLgiZjyvuqIYaa4 (二维码自动识别)

我怎么觉得我的广告有点六学?过渡一点也不优雅,强行转弯,强势恰饭。下次改进下次改进。

最后

说回到本质,学技术要学本质,但内存抖动并不是任何技术的本质。其实我今天也并不是在聊内存抖动这个词本身,而是想表达一种观点:

我们学技术,应该学得深,而且应该足够深,但不要被各种花里胡哨的词吓到,也不要被它们带着跑,我们要有自己的知识体系,有自己的成长逻辑。

我是扔物线,我不和你比高低,我只助你成长。我们下期见。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502133.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vba 循环读取单元格_利用VBA打开顺序文件,并读取

大家好,疫情施虐,国外各地更有爆发的迹象,但无论怎样,我们一定要坚信,疫情终将会过去,曙光一定会到来。后疫情时代将会是一个全新的世界,很多理念都将被打破,大多数人不会再享受体制…

linux下collada-dom编译,Building Collada

文章声明:由于COLLADA以及IDE版本的更新,本文尽量以最新的版本为准,但是不保证一定适用于当前存在的版本,仅就一些编译上遇到的问题给出一些解答,希望能对需要进行COLLADA编程的人员带来一些帮助~1、Downloading the C…

opcua客户端实现断线重连_虹科教您|实现OPC UA C/S快速部署及数据采集

想获取更多IIOT干货请点击蓝字,关注我们虹科HMI解决方案高性能高防护宽温★★★★★简介边缘HMI需要实现的主要功能包括连接到该边缘HMI的边缘设备的数据采集,实现边缘计算、提供人机接口、数据的本地存储与上传。在工业4.0的进程中,越来越多…

特征级融合_遥感影像融合的方法有哪些

遥感影像融合的方法有哪些 多种名称,常见的有 图像复合(Image Fusion) 影像融合(Image Merging)、 数据复合(Data Fusion)、 数据综合(Data Integration)、 影像综合(Image Integration)、 信息复合(Information Combination) 目的:把那些在空间和时间上…

linux系统起来时间,linux 系统时间调整

BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 1280 MBSubmit: 3127 Solved: 795[Submit][Status][Discu ...poj 1696 Space Ant (极角排序)链接:http://poj.org/problem?id1696 Space Ant …

最大值减最小值等于区间长度_呆哥数学每日一题 ——三角函数求余弦最小值...

如果想要获取往期每日一题电子版,可以加我微信:daigemath166,备注:知乎 每日一题呆哥解析:今天我们来看一道三角函数求余弦最小值的题目这里条件只有一个,那么我们第一步就是应该把两个角联系起来&#xff…

python ide在哪个文件夹_Python IDE使用汇总

Pycharm分收费和Community版,一般Community版已经足够了。安装软件包也很简单,在Setting->Project Interpreter只要点一下就可以。在中国需要增加获取包的地址,可以在Manage Repositories中增加文件地址https://pypi.python.org/pypihttp:…

mac运行linux命令,iOS:mac.app执行shell命令

报错1:错误:/bin/bash: line 1: /Users/liuyaqiang/Desktop/GitHub/KTMRobot/auto.sh: Operation not permitted解决方法:Singing&Capabilitiesy移除AppSandbox代码import Cocoaclass CommandRunner: NSObject {/** 同步执行* command: s…

go channel 缓冲区最大限制_Go语言11周年,泛型问题有望明年得到解决

作者 | 田晓旭、万佳 近日,Go 团队发布长篇博文庆祝 Go 语言开源 11 周年。 Go 团队在博文写道,“回想 Go 语言十周年庆典恍如隔世。虽然 2020 年有诸多艰难,但我们一直在推动 Go 语言的发展,其中有不少值得回忆的美好瞬间。”1 G…

python 排列组合_python 编写排列组合

python在编写排列组合是会用到 itertools 模块 排列 import itertools mylist list(itertools.permutations([A,B,C,D],4)) # 全排列 print(mylist) mylist1 list(itertools.permutations([A,B,C,D],3)) # 4个里面选3个排列 print(mylist1) #5!1*2*3*4*5#0!1#M个选N个 M&#x…

深度linux 转中文,Linux Deepin 中文Linux系统的新希望?

Linux Deepin 中文Linux系统的新希望?出处:快科技 2010-08-02 22:51:18 作者:Plum 编辑:Plum[爆料] 收藏文章前言说到国产系统,我们想到的东西可能并不多,在这个Windows垄断的领域,国产的空…

python 谷歌地图api_《Python网络编程》学习笔记--使用谷歌地理编码API获取一个JSON文档...

Foundations of Python Network Programing,Third Edition 《python网络编程》,本书中的代码可在Github上搜索fopnp下载本书的第一章中使用到了google地图的api来获取一个地址的经度和纬度,因为众所周知的原因会出现无法访问,我们…

耳机不分主从是什么意思_无延时音质好的蓝牙耳机能代替有线耳机吗—DOSS T60上手体验...

伴随着手机的更新迭代,大概是从iPhone 7的时候大家开始对手机是否有3.5mm耳机孔这个问题开始纠结起来,好像是从真无线耳机出来时大家又对3,5mm耳机孔又不是那么的纠结。此一时彼一时,大家为何对耳机接口为何有这么大的转变,就拿今…

switch安装linux教程,Freeswitch Linux安装教程 | 【韩涛博客】

大家都有一个经历,经过漫长的编译后,各种报错,经过整理后,我总结出了以下无错步骤:(一)安装编译所需要的环境包yum install -y autoconf automake libtool gcc-c ncurses-devel make zlib-devel libjpeg-devel(二)安装…

空间金字塔池化_回顾语义分割—DenseASPP (密集空洞空间金字塔池化)

引言在分辨率大,分割目标尺度范围广的语句分割任务中,长距离的上下文信息以及不同尺度的信息对于分割结果十分重要。所以为了增大卷积但感受野,常常对提取的feature map进行池化以达到感受野增大的效果,同时通过跳跃连接来结合多尺…

python软件如何安装方法_【新手必看】Python软件下载及安装教程

原标题:【新手必看】Python软件下载及安装教程 Python下载:免费开源 官网地址:https://www.python.org/downloads/ 下载对应版本Python:python-3.6.1-amd64.exe(我的电脑是window 7-64位),所以我…

如何下载linux历史版本下载,CentOS历史版本下载方法

实验室要求统一Linux版本,原来我用的是Ubuntu,现在我在的实验室是centos,我也就只能改了。实验室和个人不同,个人的Linux版本可能经常换,只要有新的版本出来,我就会去下载下来,在虚拟机里面试一…

table超出边框出现滚动条_精美横轴智能滚动条设计

如何设计一款精美的横轴智能滚动条?本文对设计过程进行了详细地介绍。页面布局页面设定新建一个页面文件,命名为【精美横轴智能滚动条设计】。在【精美横轴智能滚动条设计】页面内新建一个命名为【table】的动态面板。【底层背景】:从元件库内…

如何在python中安装matplotlib模块_Windows下为Python安装Matplotlib模块

这玩意反反复复弄了一晚上,这里详细叙述下如何安装,肯定会对大家有所帮助。首先默认大家都装了Python,这个从官网下基本不会有任何难度。 (1)Setuptools的安装 为啥先说这个,后面所有whl文件都要用这个安装…

linux 状态码的意义,HTTP状态码是什么?常见的状态码描述都有什么?

网络安全学习过程中,网络协议都有哪些相关内容?HTTP状态码是什么?HTTP状态码有什么意义吗?常见的状态码描述都有什么?很多小伙伴不是很清楚,我们来看看。什么是HTTP状态码?当浏览者访问一个网页…