想知道终止长时间运行的正则表达式匹配的技术(java matcher.find()方法).也许子类化Matcher并添加一些逻辑以在x次迭代后终止?
基本上我是使用遗传算法生成正则表达式,所以我没有很多控制它们.然后我针对某些文本测试每个文本以查看它们是否与文本的某个目标区域匹配.
因为我有点随机生成这些正则表达式,我得到了一些疯狂的东西,它吃了大量的cpu和一些find()调用需要一段时间来终止.我宁愿在一段时间后杀死它们,但不确定最好的方法.
如果有人有想法,请告诉我.
遗憾的是,在Java中对String使用正则表达式时无法指定超时.因此,如果您没有严格控制哪些模式应用于哪个输入,您可能最终会拥有消耗大量CPU的线程,同时无休止地尝试将(不那么精心设计的)模式与(恶意?)输入匹配.
我知道不推荐使用Thread#stop()的原因(请参阅http://download.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html).它们以可能在ThreadDeath异常情况下被损坏的对象为中心,然后污染正在运行的JVM环境并可能导致细微的错误.
我对这个对JVM工作有更深入了解的人的问题是:如果需要停止的线程没有任何(明显的)监视器或对程序其余部分使用的对象的引用,那么可以使用Thread#stop()吗?
我创建了一个相当防御的解决方案,能够处理与超时匹配的正则表达式.我会很高兴任何评论或评论,尤其是尽管我努力避免它们,这种方法可能导致的问题.
谢谢!
import java.util.concurrent.Callable;
public class SafeRegularExpressionMatcher {
// demonstrates behavior for regular expression running into catastrophic backtracking for given input
public static void main(String[] args) {
SafeRegularExpressionMatcher matcher = new SafeRegularExpressionMatcher(
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "(x+x+)+y", 2000);
System.out.println(matcher.matches());
}
final String stringToMatch;
final String regularExpression;
final int timeoutMillis;
public SafeRegularExpressionMatcher(String stringToMatch, String regularExpression, int timeoutMillis) {
this.stringToMatch = stringToMatch;
this.regularExpression = regularExpression;
this.timeoutMillis = timeoutMillis;
}
public Boolean matches() {
CallableThread<Boolean> thread = createSafeRegularExpressionMatchingThread();
Boolean result …Run Code Online (Sandbox Code Playgroud) 我正在使用mod安全规则https://github.com/SpiderLabs/owasp-modsecurity-crs来清理用户输入数据.我正面临cpu射击和延迟匹配用户输入与mod安全规则正则表达式.总的来说,它包含500多个正则表达式来检查不同类型的攻击(xss,badrobots,generic和sql).对于每个请求,我会查看所有参数并检查所有这500个正则表达式.我Matcher.find用来检查参数.在这种情况下,一些参数属于无限循环,我使用以下技术解决了这个问题.
消除用户请求大约需要大约500毫秒,并且cpu%会上升.我使用visualvm.java.net和我的测试套件运行程序进行了分析.
Cpu配置文件输出

请帮我减少cpu使用率和平均负载?
如何将Callable线程作为守护线程?
这是我正在尝试的.我试图执行一组线程,其中一个线程没有完成并进入无限循环.它的作用是即使执行了所有代码语句,程序的主线程也不会终止.之后主线程进入挂起模式.
这是相同的代码片段.
public class MyThread implements Callable<String> {
private int value;
public MyThread(int value) {
this.value = value;
}
@Override
public String call() throws Exception {
//Thread.currentThread().setDaemon(true);
System.out.println("Executing - " + value);
if (value == 4) {
for (; ; );
}
return value + "";
}
}
Run Code Online (Sandbox Code Playgroud)
主要计划
public class ExecutorMain {
public static String testing() {
ExecutorService executor = null;
List<Future<String>> result = null;
String parsedValue = null;
try {
executor = Executors.newSingleThreadExecutor();
List<MyThread> threads = new …Run Code Online (Sandbox Code Playgroud)