起因
一个java进程,通过top命令查看到其CPU使用量400%多(八核CPU),于是通过进程查线程,再通过线程查询调用堆栈发现是Java的replaceAll
方法在消耗CPU,再具体一点就是Java的正则表达式处理在消耗大量CPU
进程查线程,查堆栈信息看这里 Linux中找出Java程序占用大量CPU的元凶
堆栈信息如下
java.lang.Thread.state: RUNABBLE
at java.util.regex.Pattern$Curly.match1(Pattern.java:4300)
at java.util.regex.Pattern$Curly.match(Pattern.java:4236)
at java.util.regex.Pattern$start.match1(Pattern.java:3461)
at java.util.regex.Matcher.search(Matcher.java:1248)
at java.util.regex.Matcher.find(Matcher.java:637)
at java.util.regex.Matcher.replaceAll(Matcher.java:951)
at java.lang.String.replaceAll(String.java.2210)
.......
at java.lang.Thread.run(Thread.java:745)
再怎么也不可能怀疑Java本身出了问题,两个关键词,replaceAll和正则,一看就是正则表达式出的问题。
有问题的正则表达式
把目光聚集在有问题的正则表达式上,代码中有这么一句
xml = xml.replaceAll("(?is).*?<file>(.*?)</file>.*", "$1");
这段代码意思是将字符串掐头去尾,取""之间的文本,再细分一下
(?is).*?<file>(.*?)</file>.*
(?is)
不区分大小写并且多行匹配,是个flag,不用管.*?
匹配任意字符,并且是非贪婪匹配