java如何从URL中分析导致程序出现问题的方法?
我用Java编写了一个软件,通过使用代理发送HTTP请求来检查代理是否工作。它并行发送请求,使用线程池运行100多个线程
以下方法用于检查单个代理:
public boolean isWorkingProxy() {
//Case of an invalid proxy
if(proxyPort == -1) {
return false;
}
HttpURLConnection con = null;
//Perform checks on URL
//IF any exception occurs here, the proxy is obviously bad.
try {
URL url = new URL(this.getTestingUrl());
//Create proxy
Proxy p = new Proxy(this.testingType, new InetSocketAddress(this.proxyIp, this.proxyPort));
//No redirect
HttpURLConnection.setFollowRedirects(false);
//Open connection with proxy
con = (HttpURLConnection)url.openConnection(p);
//Set the request method
con.setRequestMethod("GET");
//Set max timeout for a request.
con.setConnectTimeout(this.timeout);
con.setReadTimeout(this.timeout);
} catch(MalformedURLException e) {
System.out.println("The testing URL is bad. Please fix this.");
return false;
} catch (ProtocolException e) {
System.out.println("Invalid request type provided (Not GET / POST / Valid type)");
return false;
} catch(IOException e) {
System.out.println("Failed to open connection with url using proxy.");
return false;
}
try(
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
) {
//read text response
String inputLine = null; StringBuilder response = new StringBuilder();
while((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
//A valid proxy!
return con.getResponseCode() > 0;
} catch(Exception e) {
return false;
}
}
以下代码是我如何启动线程的:
Deque<String> proxies = DB.getProxiesToCheck();
while(proxies.isEmpty() == false) {
try {
String[] split = proxies.pop().split(":");
//Submit every check for this proxy
//There are a total 7 checks right now.
for(int i = 0; i < checks.length; i++) {
executor.submit(new RunnableProxyRequest(split[0], split[1], checks[i]));
}
} catch(IndexOutOfBoundsException e) {
continue;
}
//Wait 50ms before each proxy
Thread.sleep(50);
}
现在:CPU使用率在某些时候变得相当高,我已经尝试使用JVisualVM对其进行评测。我有以下结果:
它声明我有“Abdandoned连接清理线程”,但是我的代码使用try with resources来打开HttpURLConnection
的输入流,并且我找不到任何保持打开连接的实例。除了方法中的流之外,我不打开任何其他流。此外,parseURL(Java的URL对象中使用的方法)似乎占用了我100%的CPU时间
请注意,它会更新SQL数据库以报告代理是否工作。MySQL数据库的更新是synchronized()
为什么会发生这种情况,我如何修复它
编辑
在将每个代理检查发送到exectuor服务之前,我添加了一个Thread.sleep(50);
(在上面的代码中很明显),我还将参数-XX:+UseParallelGC
添加到命令行中。它似乎持续了更长的时间,但几个小时后CPU使用率仍然会很高,程序崩溃
# 1 楼答案
outputStream也应该关闭。 同时建立100多个连接确实会消耗CPU资源,尤其是在大多数代理可用的情况下