多么痛的领悟-代码优化导致的BUG
2013-04-03 18:43
357 查看
一大早服务器报警,top一下,系统CPU负载已经飚到了15,导致无法访问!
jstack pid打印堆栈,大量解析json的线程在RUNNABLE。
忽然想到之前为了json解析的效率,放弃了现成的类库,手动做json解析,这样做的结果是效率提高了50倍以上,当时还沾沾自喜了好一阵子!
万万没想到今天忽然一条格式不合法的数据,竟然导致了死循环!
暂且不去说脏数据是如何进入到系统的,看一下解析Json的代码:
注意1处和2处,如果格式不合法就直接进行下一次循环。问题就出在这里,如果partners.substring(colonpos+1,commapos)取出来是空,进入下一次循环的时候没有更改原字符串,下次还会重复执行,导致了死循环!
很低级的一个失误!Fuck!
教训:
(1)不要轻易的优化代码。
(2)一定要做好单元测试,考虑正常分支和异常分支,正常数据和异常数据。
(3)CPU负载过高,很可能是出现了死循环!
ps:看到一个打印堆栈的方法:
jstack pid打印堆栈,大量解析json的线程在RUNNABLE。
忽然想到之前为了json解析的效率,放弃了现成的类库,手动做json解析,这样做的结果是效率提高了50倍以上,当时还沾沾自喜了好一阵子!
万万没想到今天忽然一条格式不合法的数据,竟然导致了死循环!
暂且不去说脏数据是如何进入到系统的,看一下解析Json的代码:
public static List<Long> getPartneridsFromJson(String data){ //{\"data\":[{\"partnerid\":982,\"count\":\"10000\",\"cityid\":\"11\"},{\"partnerid\":983,\"count\":\"10000\",\"cityid\":\"11\"},{\"partnerid\":984,\"count\":\"10000\",\"cityid\":\"11\"}]} //上面是正常的数据 List<Long> list = new ArrayList<Long>(2); if(data == null || data.length() <= 0){ return list; } int datapos = data.indexOf("data"); if(datapos < 0){ return list; } int leftBracket = data.indexOf("[",datapos); int rightBracket= data.indexOf("]",datapos); if(leftBracket < 0 || rightBracket < 0){ return list; } String partners = data.substring(leftBracket+1,rightBracket); if(partners == null || partners.length() <= 0){ return list; } while(partners!=null && partners.length() > 0){ int idpos = partners.indexOf("partnerid"); if(idpos < 0){ break; } int colonpos = partners.indexOf(":",idpos); int commapos = partners.indexOf(",",idpos); if(colonpos < 0 || commapos < 0){ //partners = partners.substring(idpos+"partnerid".length());//1 continue; } String pid = partners.substring(colonpos+1,commapos); if(pid == null || pid.length() <= 0){ //partners = partners.substring(idpos+"partnerid".length());//2 continue; } try{ list.add(Long.parseLong(pid)); }catch(Exception e){ //do nothing } partners = partners.substring(commapos); } return list; }
注意1处和2处,如果格式不合法就直接进行下一次循环。问题就出在这里,如果partners.substring(colonpos+1,commapos)取出来是空,进入下一次循环的时候没有更改原字符串,下次还会重复执行,导致了死循环!
很低级的一个失误!Fuck!
教训:
(1)不要轻易的优化代码。
(2)一定要做好单元测试,考虑正常分支和异常分支,正常数据和异常数据。
(3)CPU负载过高,很可能是出现了死循环!
ps:看到一个打印堆栈的方法:
写一个打印堆栈的方法: @Path(value = "/api/stackinfo") @GET public ActionResult stackinfo() { String str = "<strong>Memory:</strong>"; str +="<ol>"; str +="<li>freeMemory="+Runtime.getRuntime().freeMemory()/(1024*1024)+"M</li>"; str +="<li>totalMemory="+Runtime.getRuntime().totalMemory()/(1024*1024)+"M</li>"; str +="<li>maxMemory="+Runtime.getRuntime().maxMemory()/(1024*1024)+"M</li>"; str +="</ol>"; str +="<br/>"; str +="<strong>Thread:</strong>"; str +="<ol>"; for(Thread t : list_threads()){ str +="<li>"+t.getName()+","+t.getState()+":"+ t.getClass().getName()+"</li>"; StackTraceElement[] elems = t.getStackTrace(); str += "<ol>"; for(StackTraceElement elem : elems){ str +="<li> "+elem.toString()+"</li>"; } str += "</ol>"; } str +="</ol>"; beat.getResponse().setContentType("text/html;charset=UTF-8"); return new ContentResult(str); }
相关文章推荐
- 多么痛的领悟-代码优化导致的BUG
- 优化代码,引发了早期缺陷导致新bug
- 记录一次bug解决过程:else未补全导致数据泄露和代码优化
- 多么痛的领悟---关于RMB数据类型导致的元转分分转元的bug
- 多么痛的领悟---关于RMB数据类型导致的元转分分转元的bug
- 多么痛的领悟---关于RMB数据类型导致的元转分分转元的bug
- GCC优化导致的部分代码丢失
- Android源生代码bug导致连续发通知应用卡死
- [Bug]由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值"的解决方法(转)
- 一个由于浏览器优化导致的正则表达式直接量bug
- GIT : 记录IntelliJ IDEA 合并冲突时的一个bug(冲突解决后代码和本地仓库一样时导致merge失败)
- user模式下编译android 代码被proguard优化导致类和变量丢失
- Android源生代码bug导致连续发通知应用卡死
- phpcms审核代码处理存在bug导致审核过无变化/模板基于审核状态将误判问题
- Bug经典回放四--别让编译器优化掉你想要执行的代码
- BUG:由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值
- Android源生代码bug导致连续发通知应用卡死
- 编译器自动优化导致代码可以先后写的问题
- 20140829-复制粘贴网上代码导致的bug
- findbugs 查找bug优化代码