2024年Java最全从V8源码分析一个JS 数组的内存占用问题,java开发框架面试题

总结

虽然面试套路众多,但对于技术面试来说,主要还是考察一个人的技术能力和沟通能力。不同类型的面试官根据自身的理解问的问题也不尽相同,没有规律可循。

上面提到的关于这些JAVA基础、三大框架、项目经验、并发编程、JVM及调优、网络、设计模式、spring+mybatis源码解读、Mysql调优、分布式监控、消息队列、分布式存储等等面试题笔记及资料

有些面试官喜欢问自己擅长的问题,比如在实际编程中遇到的或者他自己一直在琢磨的这方面的问题,还有些面试官,尤其是大厂的比如 BAT 的面试官喜欢问面试者认为自己擅长的,然后通过提问的方式深挖细节,刨根到底。

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

const b = new Array(99999);

b[99999] = undefined;

我们通过 node --inspect-brk 来分别运行这两段代码,在代码运行的最开始和结束的时候分别task heap snapshot,分析对应的内存占用信息如下:

可以发现第二段代码的内存占用明显要小于第一段,那么问题就出现在这个 99999 的越界赋值上面。

在V8代码(v8/src/objects/js-array.h#L19)中有很明确的标注,数组有两种模式,快数组和慢数组,在数组初始化时,默认的存储方式为快数组(v8/src/objects/js-objects.h#L317),其内存占用是连续的,而慢数组会使用HashTable来进行数据存储。另外数组会分为压紧(Packed)的和有洞的(Holey)两种,例如 [‘a’, ‘b’, ‘c’] 这样的数组长度为3,数组索引0、1、2均有值,那么就认为是Packed;而对于 [‘a’,‘d’] 这样的数组,长度为4,但是索引1、2位置并没有进行初始化赋值,那么就认为是Holey。当数组出现了较大空洞的时候,内存明显是被浪费了。

V8中对于大型空洞数组进行了优化,在V8博客(https://v8.dev/blog/fast-properties)中进行说明了这一点,对于非常大的Holey数组来说,FixedArray会造成内存浪费,所以会使用字典来节约内存,也就是会使用慢数组模式。

使用v8-debug分别对最开始的两段代码进行调试:

可以很明显的看到,第一个数组为FixedArray,而第二个数组为Dictionary,那么为什么只有第二个数组转换为了字典模式呢?

在V8中JSArray是继承于JSObject的,所以当设置属性的时候,会依次执行 Object::SetProperty 、 Object::AddDataProperty 、 JSObject::AddDataElement 、 ShouldConvertToSlowElements ,回到V8代码中,ShouldConvertToSlowElements这个方法,它是用来判断是否将一个数组转换为慢模式(Dictionary)(v8/src/objects/js-objects-inl.h#L794):

从上面的代码可以看到,当设置 99998 的时候,索引小于当前容量的时候,返回值为false,也就是不进行转换。而当设置 99999 这个索引的值的时候,因为超出了原来的FixedArray容量,那么就会进行扩容,扩容的算法(v8/src/objects/js-objects.h#L540)为容量 + 容量 /2 + 16,那么原来 99999 的容量就会扩容放大到 15万。

然后会执行 GetFastElementsUsage 来获取原来的数组中非空洞(v8/src/objects/js-objects.cc#L4725)的元素数量,乘以 kPreferFastElementsSizeFactor(值为3) 与 kEntrySize (值为2) ,与新的容量长度进行对比,如果小于新的容量长度,那么就转换为慢数组。

分享

首先分享一份学习大纲,内容较多,涵盖了互联网行业所有的流行以及核心技术,以截图形式分享:

(亿级流量性能调优实战+一线大厂分布式实战+架构师筑基必备技能+设计思想开源框架解读+性能直线提升架构技术+高效存储让项目性能起飞+分布式扩展到微服务架构…实在是太多了)

其次分享一些技术知识,以截图形式分享一部分:

Tomcat架构解析:

算法训练+高分宝典:

Spring Cloud+Docker微服务实战:

最后分享一波面试资料:

切莫死记硬背,小心面试官直接让你出门右拐

1000道互联网Java面试题:

Java高级架构面试知识整理:

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

实战项目源码】](https://bbs.csdn.net/topics/618154847)收录**

需要这份系统化的资料的朋友,可以点击这里获取

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值