诊断不正确的 JSONArray 引起的死循环导致 CPU 使用率高
最近有个应用经常 CPU 使用率经常非常高, 一旦升上去, 很难再下来, 除非进行重启. 使用 htop 观察, 出现 CPU 使用率高的并不是一个线程. 然后使用 async-profiler 查看, 发现代码很像死循环, 99%以上的栈都被 JSONArray 初始化占用了:
看上去一个很正常的 JSONArray 初始化为什么会占用这么多 CPU 时间呢? 难道是处理的业务较多? 一开始开发人员认为最近的促销导致业务量暴涨导致的. 其实做一个 heap dump 很快发现了事情的元凶.
我们的这段代码是这么写的(这里只是展示基本含义, 没做其它验证):
String str = "some string";
if (str.startWith("[")) {
new org.codehaus.jettison.json.JSONArray(str);
} else {
//something else
}
问题就出现在这个 str, 如果它的格式有问题, 不是真正的数组, 那么就会出现问题, 比如下面的代码:
public static void main(String[] args) {
String str = "[*/*A25] **";
try {
System.out.println("start");
System.out.println(new JSONArray(str));
System.out.println("end");
} catch (JSONException e) {
e.printStackTrace();
}
}
如果 debug 上面的代码, 就会发现出现了死循环, 线程再也无法退出. stuck 在了 JSONTokener L179 ~ 188 -> next() -> back() -> next(). 一直 next(), back().
于是给这个 lib 提了一个 issue: https://github.com/jettison-json/jettison/issues/36