Android查找dalvikvm疯狂调用GC原因

在移动学习应用中,翻页操作导致频繁垃圾回收(GC)。问题源于使用String拼接大量数据,改为StringBuilder有效解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

将原生书demo做完后,合入到移动学习中。发现翻页时疯狂调用GC,GC代码如下:

11-17 00:56:35.659 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8097K, 23% free 68244K/87592K, paused 62ms, total 62ms
11-17 00:56:35.719 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8049K, 23% free 68298K/87592K, paused 49ms, total 49ms
11-17 00:56:35.779 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8164K, 23% free 68302K/87592K, paused 47ms, total 47ms
11-17 00:56:35.839 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8055K, 22% free 68350K/87592K, paused 48ms, total 48ms
11-17 00:56:35.909 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8101K, 22% free 68354K/87592K, paused 53ms, total 53ms
11-17 00:56:35.969 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8149K, 23% free 68311K/87592K, paused 49ms, total 49ms
11-17 00:56:36.029 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8140K, 22% free 68362K/87592K, paused 48ms, total 48ms
11-17 00:56:36.079 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8172K, 22% free 68366K/87592K, paused 47ms, total 47ms
11-17 00:56:36.139 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8200K, 23% free 68320K/87592K, paused 47ms, total 47ms
11-17 00:56:36.199 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8067K, 22% free 68323K/87592K, paused 47ms, total 47ms
11-17 00:56:36.259 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8186K, 22% free 68326K/87592K, paused 47ms, total 47ms
11-17 00:56:36.319 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8042K, 22% free 68380K/87592K, paused 50ms, total 50ms
11-17 00:56:36.379 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8171K, 22% free 68360K/87592K, paused 48ms, total 48ms
11-17 00:56:36.439 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8044K, 22% free 68364K/87592K, paused 49ms, total 49ms
11-17 00:56:36.509 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8129K, 22% free 68366K/87592K, paused 54ms, total 54ms
11-17 00:56:36.579 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8216K, 23% free 68245K/87592K, paused 55ms, total 55ms
11-17 00:56:36.639 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 7919K, 22% free 68377K/87592K, paused 52ms, total 52ms
11-17 00:56:36.699 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8108K, 22% free 68379K/87592K, paused 48ms, total 48ms
11-17 00:56:36.759 4674-4674/com.handsome.hxm D/dalvikvm: GC_FOR_ALLOC freed 8181K, 22% free 68382K/87592K, paused 47ms, total 47ms
...........

一共调用了大概300次GC

找问题吧,以为是解析书时出现问题,便在adapter的getview()方法中,解析书的方法前后加上Log打印:

Log.i("","position " + position + "; 解析开始时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
positionPageNode = parser.parseTargetPageHtml(path, hpm.getHtmlPageNodeNumber());
Log.i("","position " + position + "; 解析结束时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));		

实际运行过程中却发现,只打印结束时间,不打印开始时间,简直牛逼死了。查看日志发现GC确实是在这个函数中打印的。

贴出parseTargetHtml方法:

public PageNode parseTargetPageHtml(String fileName, int position) throws Exception {
		String szContent = openFile(fileName);

		parser = Parser.createParser(szContent, "UTF-8");

		// 1 load pageNodes
		NodeFilter filter = new HasAttributeFilter("class", "page ui-droppable");

		String[] fileNames = fileName.split("/");
		String htmlName = fileNames[fileNames.length-1];

		NodeList nodes;
		Node[] nodesList = null;
		if(!common.allNodeList.containsKey(htmlName)){
			Log.i("","allNodeList中不包含该key");
			nodes = parser.extractAllNodesThatMatch(filter);
			if(nodes != null){
				common.allNodeList.put(htmlName, nodes);
				nodesList = nodes.toNodeArray();
			}
		}else{
			Log.i("","allNodeList中包含该key,直接取出");
			nodes = common.allNodeList.get(htmlName);
			if(nodes != null)
				nodesList = nodes.toNodeArray();
		}


		if(nodesList != null && nodesList.length > position){
			Node pageNode1 = nodesList[position];

			PageNode page = new PageNode();
			common.threadList.clear();
			List<ElementNode> elementNodes = new ArrayList<ElementNode>();
			for (Node eleNode : pageNode1.getChildren().toNodeArray()) {
				elementNodes.addAll(loadTagNode(eleNode));
			}
			for (Thread thread : common.threadList) {
				thread.join();
			}
			page.setElementNodes(elementNodes);

			return page;
		}else{
			return null;
		}

	}

debug这个函数,发现是走到openFile()这个函数时,疯狂调用GC,进去一看,大开眼界:

private String openFile(String fileName) {
		try {
			BufferedReader bis = new BufferedReader(new InputStreamReader(new FileInputStream(new File(fileName)), "UTF-8"));
			String szContent = "";
			String szTemp;

			while ((szTemp = bis.readLine()) != null) {
				szContent += szTemp + "\n";
			}
			bis.close();
			return szContent;
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}
while当中竟然用String+=.....

去找当事人,他说当时着急,随便这么一写。。。。。

换成StringBuilder和.append()就好了

String += 数据量大时真是害死人啊










这是com.oplus.location进程的一个调用堆栈他频繁GC回收"--------------------------------------------------------------------------------------------------------------- Total: 2,834,104 Count: 81,337 Avg: 34.8 Percent: 96.66% --------------------------------------------------------------------------------------------------------------- java.lang.Throwable.nativeGetStackTrace(Native method) java.lang.Throwable.getOurStackTrace(Throwable.java:869) java.lang.Throwable.printStackTrace(Throwable.java:686) java.lang.Throwable.printStackTrace(Throwable.java:753) com.amap.location.support.n.a.b(ALLog.java:98) com.amap.location.support.n.a.a(ALLog.java:47) com.amap.location.c.a.b.a(LocationDbHelper.java:337) com.amap.location.c.a.b.a(LocationDbHelper.java:157) com.amap.location.k.d.a.a.a(DBProvider.java:139) com.amap.location.k.d.d.d$a.a(DataTunnel.java:166) com.amap.location.k.c.a.d(SaveController.java:254) com.amap.location.k.c.a.b(SaveController.java:244) com.amap.location.k.c.a.a(SaveController.java:177) com.amap.location.k.d.d.d.a(DataTunnel.java:88) com.amap.location.k.d.a.a(UpTunnelContainer.java:121) com.amap.location.k.d.c$b.a(UpTunnelManager.java:217) com.amap.location.c.b.a$1.handleMessage(AmapHandlerImpl.java:32) android.os.Handler.dispatchMessage(Handler.java:112) android.os.Looper.loopOnce(Looper.java:288) android.os.Looper.loop(Looper.java:393) android.os.HandlerThread.run(HandlerThread.java:85) --------------------------------------------------------------------------------------------------------------- Total: 97,920 Count: 2,808 Avg: 34.9 Percent: 3.34% --------------------------------------------------------------------------------------------------------------- java.lang.Throwable.nativeGetStackTrace(Native method) java.lang.Throwable.getOurStackTrace(Throwable.java:869) java.lang.Throwable.printStackTrace(Throwable.java:686) java.lang.Throwable.printStackTrace(Throwable.java:753) com.amap.location.support.n.a.b(ALLog.java:98) com.amap.location.support.n.a.a(ALLog.java:47) com.amap.location.c.a.b.a(LocationDbHelper.java:337) com.amap.location.c.a.b.a(LocationDbHelper.java:157) com.amap.location.k.d.a.a.a(DBProvider.java:139) com.amap.location.k.d.d.d$a.a(DataTunnel.java:166) com.amap.location.k.c.a.d(SaveController.java:254) com.amap.location.k.c.a.a(SaveController.java:213) com.amap.location.k.c.a.a(SaveController.java:17) com.amap.location.k.c.a$1.a(SaveController.java:126) com.amap.location.c.b.a$1.handleMessage(AmapHandlerImpl.java:32) android.os.Handler.dispatchMessage(Handler.java:112) android.os.Looper.loopOnce(Looper.java:288) android.os.Looper.loop(Looper.java:393) android.os.HandlerThread.run(HandlerThread.java:85) " 总申请内存2,932,024K 堆栈索引"java.lang.Throwable.nativeGetStackTrace(Native method) java.lang.Throwable.getOurStackTrace(Throwable.java:869) java.lang.Throwable.printStackTrace(Throwable.java:686) java.lang.Throwable.printStackTrace(Throwable.java:753) com.amap.location.support.n.a.b(ALLog.java:98) com.amap.location.support.n.a.a(ALLog.java:47) com.amap.location.c.a.b.a(LocationDbHelper.java:337) com.amap.location.c.a.b.a(LocationDbHelper.java:157) com.amap.location.k.d.a.a.a(DBProvider.java:139) com.amap.location.k.d.d.d$a.a(DataTunnel.java:166) " 找一下那个函数或者方法有问题
最新发布
07-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值