一千万个身份证号在 java 中需要多少内存

用户头像
华宇法律科技
关注
发布于: 2020 年 07 月 20 日
一千万个身份证号在java中需要多少内存

String对象的内存占用



前些时间和一个小朋友聊一些技术的内容,我让他回去验证一下一千万个身份证号在java中要耗费多少内存,他写了个程序,得出来的结论是599MB,我掐指一算,如果通过数学推算的话,差了100多M,于是就和他赌10块钱,谁输谁给十块钱。这篇贴子就是为了要赚那10块钱。



这位同学的代码是这么写的 





有两个问题



  1. 代码不太好看,标量命名a,b啥的

  2. for循环里是用同一个变量名来引用String对象,我判断他这么写的目的是避免再拿一个数组来存放的话,数组的内存占用就会带来误差,但是这么写的话就会引出GC的影响。



不过我不是低估了这个小朋友,他说他把新生代内存调到1G了,而且加了-XX:+PrintGCDetails参数,从日志来看,没有进行GC。 



这个解释确实合情合理,让我竟无语凝噎。

 到这份上了,那就来验证吧。



数学推算



  1. 在java中,所有对象的内存占用都会是8个字节的倍数,如果少于8个字节的倍数,则向上对齐到8的倍数。

  2. 身份证是18位,在内存中是以char数组存储,一个空的char数组本身要16个字节,一个char是2个字节,所以是16+18*2=52个字节。char数组本身也是一个特殊的对象,对象头是8个字节,外加一个数组长度是int类型,4个字节,一共12个字节,不是8的倍数,向上对齐到16。

  3. 如果数组最终内存占用字节数不是8的倍数,则向上对齐到8的倍数,52不是8的倍数,则向上取56,占用56个字节。

  4. 一个空String是24个字节,加上char数组的56个字节=80个字节,是8的倍数。

  5. 1000万个身份证号,读到内存中,是1000万个String,总内存数是80*1000万字节=762.94M

  6. 如果嫌麻烦,也可以用这个速算公式



String对象的最小内存占用 (bytes) = 8 * (int) ((((char数量) * 2) + 45) / 8)



实验推算



基于数学得出来的是理论值,而且对于JVM里内存对象的占用,要做很深入的研究才能完全掌握,比如不同的机器、操作系统、jdk、jvm参数配置等等,都会影响到内存的占用。数学推算可做为一个合理的值范围,不会出现大的偏差,最好还是通过实验来验证。



char数组的真实内存情况



  1. 通过jps获得进程ID

  2. 通过jamp导出对应进程的内存信息

  3. 通过MAT工具分析char数组的内存情况 





基于上图,我们选出一些常规值进行分析



  • char[0]=16字节

  • char[2]=24字节

  • char[8]=32字节

  • char[13] =48字节

  • char[19] =56字节

  • char[36] =88字节

  • char[348] =712字节

  • char[14305] =28632字节



我们在写程序和排查问题时,很难说所有的问题,你都有相应的知识储备。在解决问题时,最重要的点是思路,结合我们已有的知识,从问题发现规律,理清头绪。以上面char数组的内存情况来分析,我们可以有以下思路



  1. char是两个字节,这是java基础知识

  2. 即便是一个空的char数组,它也要16个字节

  3. char[2]比char[0]多8个字节,而不是4个字节,为什么?

  4. 为什么所有的内存占用都是8的倍数,不管怎么样都是8的倍数,这是不是造成char[2]比char[0]多8个字节的原因,JVM有内存对齐机制



结论:char数组的内存占用=16+数组长度*2,如果最终结果不是8的倍数,则对齐到8的倍数。



String也可以用同样的方式来推导。



直接代码验证



  • 空String数组,size为1000万,内存消耗为55728720字节 



  • String数组,内有1000万身份证号,内存消耗为841801640字节



  • 二者相减,得786,072,920字节,等于750MB,与数学推算的762MB误差在2%以内。



后记



  1. 以上结论和推算都是基于jdk1.8.0_92,不同版本可能会有差别。

  2. 分析问题就和做数独一样,已知5个数,要把所有的数字解出来,中间可能需要试错。

  3. 学习的好处有两点知识面更广,就相当于拿到了一个剑的数独,81个数,已经填充了78个数了,你只需要解三个数就行你分析问题的思路会更解析,你有更多解数独的套路,顺着这些套路就可以一步步解答出来



参考资料





发布于: 2020 年 07 月 20 日 阅读数: 15
用户头像

华宇法律科技

关注

还未添加个人签名 2020.05.21 加入

还未添加个人简介

评论

发布
暂无评论
一千万个身份证号在java中需要多少内存