全国咨询热线:400-123-4567

小程序的那些组合_动态内存分配导致影响Javasc

类别:媒体报道 发布时间:2021-01-08 浏览人次:

动态内存分配导致影响Javascript性能的问题       今天小编就为大家分享一篇关于动态内存分配导致影响Javascript性能的问题,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

内存分配对性能的影响是很大的,分配内存本身需要时间,垃圾回收器回收内存也需要时间,所以应该尽量避免在堆里分配内存。不过直到最近优化HoLa cantk时,我才深刻的体会到内存分配对性能的影响,其中有一个关于arguments的问题挺有意思,写在这里和大家分享一下。

我要做的事情是用webgl实现canvas的2d API(这个话题本身也是挺有意思的,有空我们再讨论),drawImage是一个重要的函数,游戏会频繁的调用它,所以它的性能至关重要。drawImage的参数个数是可变的,它有三种形式:

drawImage(image, x, y) drawImage(image, x, y, width, height) drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)

第一个版本大概是这样实现的:

function Context() {
Context.prototype.drawImage3 = function(image, x, y) {
 this.drawImage9(image, 0, 0, image.width, image.height, x, y, image.width, image.height);
Context.prototype.drawImage5 = function(image, dx, dy, dw, dh) {
 this.drawImage9(image, 0, 0, image.width, image.height, dx, dy, dw, dh);
Context.prototype.drawImage9 = function(image, sx, sy, sw, sh, dx, dy, dw, dh) {
 //DO IT
Context.prototype.drawImage = function(image, a, b, c, d, e, f, g, h) {
 var n = arguments.length;
 if(n === 3) {
 this.drawImage3(image, a, b);
 }else if(n === 5) {
 this.drawImage5(image, a, b, c, d);
 }else if(n === 9) {
 this.drawImage9(image, a, b, c, d, e, f, g, h);
}

为了方便说明问题,我把测试程序独立出来:

var image = {width:100, height:200};
var ctx = new Context();
function test() {
 var a = Math.random() * 100;
 var b = Math.random() * 100;
 var c = Math.random() * 100;
 var d = Math.random() * 100;
 var e = Math.random() * 100;
 var f = Math.random() * 100;
 var g = Math.random() * 100;
 var h = Math.random() * 100;
 for(var i = 0; i 1000; i++) {
 ctx.drawImage(image, a, b);
 ctx.drawImage(image, a, b, c, d);
 ctx.drawImage(image, a, b, c, d, e, f, g, h);
window.onload = function() {
 function loop() {
 test();
 requestAnimationFrame(loop);
 requestAnimationFrame(loop);
}

用chrome的Profile查看CPU的使用情况时,我发现垃圾回收的时间比例很大,一般在4%以上。当时并没有怀疑到drawImage这个函数,理由很简单:

这个函数很简单,它只是一个简单的分发函数,而drawImage9的实现相对来说要复杂得多。

这里看不出有动态内存分配,也没有违背arguments的使用规则,只是使用了它的length属性。

加trace_opt和trace_deopt参数运行时,drawImage被优化了,而且没有被反优化出来。

Chrome的内存Profile只能看到没有被释放的对象,用它查看内存泄露比较容易。这里的问题并不是泄露,而是分配了然后又释放了,V8采用的分代垃圾回收器,这种短时存在的对象是由年轻代回收器管理器负责的,而年轻代回收器使用的半空间(semi-space)算法,这种大量短时间生存的对象,很快会耗尽其中一半空间,这时回收器需要把存活的对象拷贝到另外一半空间中,这就会耗费大量时间,而垃圾回收时会暂停JS代码执行,如果能避免动态内存分配,减少垃圾回收器的工作时间,就能提高程序的性能。

没法在Chrome里查看动态分配内存的地方(呵呵,后面证实是我的无知),只好去硬着头皮看V8 JS引擎的代码,看看能不能找到频繁分配内存的地方,后来找到了V8统计内存分配的代码:

void Heap::OnAllocationEvent(HeapObject* object, int size_in_bytes) {
 HeapProfiler* profiler = isolate_- heap_profiler();
 if (profiler- is_tracking_allocations()) {
 profiler- AllocationEvent(object- address(), size_in_bytes);
 if (FLAG_verify_predictable) {
 ++allocations_count_;
 // Advance synthetic time by making a time request.
 MonotonicallyIncreasingTimeInMs();
 UpdateAllocationsHash(object);
 UpdateAllocationsHash(size_in_bytes);
 if (allocations_count_ % FLAG_dump_allocations_digest_at_alloc == 0) {
 PrintAlloctionsHash();
 if (FLAG_trace_allocation_stack_interval 0) {
 if (!FLAG_verify_predictable) ++allocations_count_;
 if (allocations_count_ % FLAG_trace_allocation_stack_interval == 0) {
 isolate()- PrintStack(stdout, Isolate::kPrintStackConcise);
}

HeapProfiler已经有了内存分配的统计代码,Chrome里应该有对应的接口啊。再去看Chrome的Profile相关界面,最后发现需要在设置里勾选Record heap allocation stack traces,然后使用Record heap allocations功能,查看结果时选择Allocations,可以看到每个函数分配内存的次数。有时一个问题折腾你好久,解决之前百思不得其解,觉得难得不得了,而解决之后忍不住要苦笑,原来只是一层窗户纸!

虽然还是不知道导致动态内存分配的原因(谁知道请告诉我),至少可以想法规避它:

Context.prototype.drawImage = function() {
 var n = arguments.length;
 if(n === 3) {
 this.drawImage3.apply(this, arguments);
 }else if(n === 5) {
 this.drawImage5.apply(this, arguments);
 }else if(n === 9) {
 this.drawImage9.apply(this, arguments);
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对凡科的支持。如果你想了解更多相关内容请查看下面相关链接

推荐阅读

【上海网站优化】这样才能让百度中意你

您的部位: > 新闻报道新闻资讯 > 企业网站建设 > 【上海市seo优化】那样才可以让百度搜索钟意你新的一年里seo优化该怎样做才能让百度搜索钟意你,在2018有许多朋友问网编,为何一些...

2021-01-12
小程序发布流程_详解angularJs中自界说directive的数

详细说明angularJs中自定directive的数据信息互动 本文关键详细介绍了详细说明angularJs中自定directive的数据信息互动,网编感觉挺好的,如今共享给大伙儿,也给大伙儿做下参照。一...

2021-01-12
小程序界面设计模板_JavaScript自界说文本框光标

JavaScript自定文字框鼠标光标 文字框(input或textarea)的鼠标光标没法改动款式(除开根据color改动鼠标光标色调)。但小编期待本人建立自身的网站时,文字框的鼠标光标有归属于...

2021-01-12
网站推行需求剖析的根本数据目标【凡科】广州

重要词:网站实行要求分析的压根数据信息总体目标 现有 13 人访问 为何要开展网站数据信息分析?1、立即把握网站实行的实际效果,减少盲目跟风性;2、分析各种各样互联网营销推广...

2021-01-12
网站制作,专题活动网站建设

主题活动企业网站建设的要求 主题活动网站怎样反映特点,精准定位爱好群体? 主题活动网站怎样用品牌形象化的語言呈现商品的特点? 主题活动网站怎样吸引住潜在用户选购? 主题...

2021-01-12
解读《百度移动搜索建站优化白皮书》

百度搜索惊雷优化算法不久不久,又接到了百度搜索搜狗引擎建网站提升市场研究报告。以便让众多网站站长充足掌握百度搜索检索模块标准,并依据标准有效安全性基本建设网站、提...

2021-01-12
X

400-8700-617400-123-4567
企业邮箱1497847554@qq.com
官方微信