Android如何解决大循环中new语句或者某些方法引发的频繁的GC_FOR_ALLOC耽误很长时间?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android如何解决大循环中new语句或者某些方法引发的频繁的GC_FOR_ALLOC耽误很长时间?相关的知识,希望对你有一定的参考价值。

我想在一个文件里直接顺序搜索一个字符串,同样是没有索引的数据库就2秒就能搜索完的任务我需要几乎40秒,我的算法就是O(n)的正常遍历算法,绝大部分时间都浪费在GC_FOR_ALLOC上,这是为什么?
求问:如何才能不等待这么长时间?或者如何才能避免GC_FOR_ALLOC?(主动调用System.gc()会比这个GC_FOR_ALLOC还要慢)

1.代码我已经尝试很多方法,所以乱套了,大概思想和数量级如下:
for(int i=0;i<150000;i++)
byte[] lengthByte=new byte[3];
inputStream.read(lengthByte);
int length=Byte2Int(lengthByte);

byte[] content=new byte[length];
inputStream.read(content);
MyMessage mc=MyMessage.parseFrom(content);
if (mc.getString().contains(inputText))
//Do someting


这个过程非常的缓慢(20秒),基本上都是GC_FOR_ALLOC。

2.再次尝试直接把这15万个MyMessage直接读到一个大byte[巨大]里会很快,但是在这个大byte[]里面截取每一段查找又一样会造成很多GC

3.再次尝试用ObjectInputStream把所有的Message合成一个ArrayList对象,读出这个Object,再强制转换成ArrayList<MyMessage>,结果读出这个Object的过程一样很缓慢。

4.尝试只存储一些字符串,用readline,读取速度大幅增加(很少的GC),但是稍微有点处理(例如toLowerCase或者一些解码),速度立马下降很多倍(多出很多GC_FOR_ALLOC)

你尝试把一些需要经常使用的变量定义到for循环外试试看 比如 byte[] content 这样应该可以避免频繁被回收追问

一个是content的长度是变的,一个是parseFrom这样的方法实际里面我觉得也是new了一个类,还是造成了回收……如果能用一个固定长度的字符数组存储这些字符串就能把byte[] content写在外面,但是怎么才能把长短不一的字符串Message写成一个固定长度的byte[]呢? 就是写成了再parseFrom的时候也一样new,也还是会回收

参考技术A 我也遇到和你类似的问题,不知道你解决了没有?

以上是关于Android如何解决大循环中new语句或者某些方法引发的频繁的GC_FOR_ALLOC耽误很长时间?的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中,如何像在谷歌地图中一样显示带有方角的警报对话框?

Android - 停止循环 NEW_OUTGOING_CALL 事件?

如何使我的多个 if 语句起作用?或者最好如何在我的代码中使用嵌套循环

如何使用python语句跳出循环

python语言如何结尾?

for循环的妙用