解决我们自动化工具内存溢出/性能低下的问题

最近做了一个5分的Story,要解决我们excel(基于Key列的值)比对工具内存和性能问题。拿了很多不同大小的文件测试下来,发现当重复记录很多(Key列的值相同,这里的Key列,就跟数据库表的key column一个意思),会内存溢出。溢出的代码行竟然是非常常见的 String s = intNumber + “”,即把一个int值转成一个String…而且这个写法在内存溢出的方法体里随处可见。琢磨了又琢磨,也google了一阵子,intNumber + ""实际上是new了一个StringBuilder,然后用StringBuilder把int转成String的。这种做法略显Heavy(昂贵)啊。

于是我尝试着用了Integer.toString(int)来转,这种的话呢,开销会比StringBuilder小一点,然而并没有解决out of memory这个问题。
最后,没办法,硬着头皮一点点把那块的逻辑看懂(异常复杂的逻辑,300行的代码,感受一下我的绝望),然后一顿改,再一顿测试,结果还比较令人满意。

公司内网的代码不能拿出来,就只能列一下我改了哪些个点:

  • 首先,将Map数据结构改成了List< String >,原始逻辑里面,循环每一行数据,然后把列名以及该列的值作为Key-value存到一个Map里。也就是说,文件里有6万行数据,那么循环里面就建了6万个Map…还是有点昂贵的,使用Map,空间换时间,于是我就想了一个不损坏效率的招,并且不用Map
  • 在重复记录比较逻辑里,原始逻辑有两层循环,做了一堆在我看来是很无聊的计算,就是在这里,出现了很多我上面写的int转string的操作,十分费解。我联合很后面用到这块结果的方法一起看,才把原作者的意思看懂…就是想干这么个事儿啊!!!简单啊!用得着两层循环吗??6万条重复记录,那就是6万 * 6万次循环呐!于是我把两层循环改成前后两个循环,总过也就6万 + 6万次循环。50MB以内的CSV文件比对就再也没有内存溢出过了,并且效率还比以前快。
  • 除了改内存和性能问题,我发现,工具还有个问题,当它OutOfMemory时,这个Error(注意,不是Exception)没有被捕捉,导致工具界面上还显示running实际上早就内存溢出了。不可接受,因为用户用我们的工具的话,就会被误导,他可能会认为工具运行的很慢,跑了很久都出不来结果,实际上工具99.99%的可能性是早就内存溢出挂掉了…翻了翻代码,找到原因了,在catch里面,只catch了Exception…而OutOfMemory不是exception,是Error,OutOfMemory --> VirtualMachineError --> Error --> Throwable. 所以做了如下改动,GUI界面就不会假running了
catch (Exception e) 
-->
catch (Exception | OutofMemoryError e)

最后提一下,为何50MB的csv比对会溢出,因为这个数据它太宽了,175个列,在重复记录比较那里呢,175个列会被拓宽成175 * 2 + 3列,要对每个列的值做一些统计运算,6万条重复记录的话呢,String[]数组里6万行,每一行有175 * 2 + 3列,每一列的值都要给它填上一个统计数值(int转String)。又因为String类型是不可变的,每次都其实是new String = int 转 String,所以溢出了。

附上我的测试结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值