“线程中的异常”;“主要”;java.lang.OutOfMemoryError:无法在http调用期间创建新的本机线程
有时我会得到一个运行时错误如下“线程中的异常”;“主要”;java.lang.OutOfMemoryError:无法在http调用期间创建新的本机线程,java,out-of-memory,Java,Out Of Memory,有时我会得到一个运行时错误如下 Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.addWo
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.addWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.execute(Unknown Source)
at okhttp3.internal.connection.RealConnectionPool.put(RealConnectionPool.kt:101)
at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:258)
at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:109)
at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:77)
at okhttp3.internal.connection.Transmitter.newExchange$okhttp(Transmitter.kt:162)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:35)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:82)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:84)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:71)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184)
at okhttp3.RealCall.execute(RealCall.kt:66)
at com.ids.decoretorPatternHttpCall.MTConnect.httpCall(MTConnect.java:39)
at com.ids.factoryPatternProtocol.CallFactory.checkProtocol(CallFactory.java:100)
at com.ids.factoryPatternProtocol.CallFactory.listDevices(CallFactory.java:46)
at com.ids.main.IdsMain.main(IdsMain.java:94)
经过多次检查,我会明白发生了什么。当设备关闭时,应用程序收到连接超时,此事件抛出上述错误。我在网上读过一些关于这个问题的话题,应该是循环代码。但是现在这个应用程序已经运行了2个小时,并且运行良好
方法,该方法具有调用httpcall()的循环。MTConnect的构造函数接收服务器名称(ip)和端口。
mt.httpCall()返回字节[]的缓冲区,否则捕获异常(IOException)。但在这种情况下,我摆脱了记忆错误
@Override
protected void checkProtocol(List<DeviceMTConnect> devicesFactory, int line, DeviceDAO devDAO, Logger logger, ConsoleHandler ch, long minute) {
DeviceMTConnect device = null;
long time = 0;
int i = 0;
if (minute > 0) {
time = minute * 60 * 1000L;
}
for (DeviceMTConnect d : devicesFactory) {
d.setLinea(linea);
d.setDeviceState(1);
// System.out.println(d);
}
while (true) {
try {
while (i < devicesFactory.size()) {
devicesFactory.get(i).setStatoDevice(devDAO.getDeviceStatus(devicesFactory.get(i).getDeviceCode(), logger, ch));
if (devicesFactory.get(i).getDeviceState() > 0) {
if (devicesFactory.get(i).getProtocol().equalsIgnoreCase(PROT1)) {
device = devicesFactory.get(i);
MTConnect mt = new MTConnect(device.getIp(), device.getPort());
ParserMTConnect pmtConnect = new ParserMTConnect()
pmtConnect.parser(mt.httpCall(), device, logger, ch);
//System.out.println();
}
if (device.getProtocol().equalsIgnoreCase(PROT2)) {
}
i++;
Thread.sleep(SleepingTime);
} else {
i++;
}
}
} catch (InterruptedException e) {
logger.warning(e.getMessage());
Utility.checkDeviceState(devDAO, device, logger, ch, time);
} catch (NumberFormatException e) {
logger.warning(e.getMessage());
Utility.checkDeviceState(devDAO, device, logger, ch, time);
} catch (IOException e) {
logger.warning(e.getMessage());
Utility.checkDeviceState(devDAO, device, logger, ch, time);
} catch (ParserConfigurationException e) {
logger.warning(e.getMessage());
Utility.checkDeviceState(devDAO, device, logger, ch, time);
} catch (SAXException e) {
logger.warning(e.getMessage());
Utility.checkDeviceState(devDAO, device, logger, ch, time);
} catch (ParseException e) {
logger.warning(e.getMessage());
Utility.checkDeviceState(devDAO, device, logger, ch, time);
} finally {
if (i < devicesFactory.size()) {
i++;
} else if (i == devicesFactory.size()) {
i = 0;
}
}
}
}
我本想抓住OutOfmemoryError,但我在StackOverflow上发现:
如您所知,错误往往是应用程序结束的信号。它通常无法从中恢复,并且会导致您的VM退出。除了在退出之前可能记录或显示和适当的消息外,不应捕获它们
我正在试图找出这个错误的原因。这应该会有帮助,谢谢你的建议。我发现了这个工具。我正在分析我的堆栈跟踪,我相信我已经理解了这个问题。它应该在这个OkHttp连接池线程上。我会找到一种方法来管理httpcall()方法上的线程池。我考虑过fork\join框架。很明显,任何建议都将受到感谢。我遇到了与您相同的问题,我的问题已经解决了。>详细信息:编写OkHttpClient的人建议您只有一个实例,跨线程共享:
public class MTConnect extends URLPath {
public MTConnect(String serverIP, String port) {
super(serverIP, port);
}
private byte[] buffer;
public String getComponetPath()
{
return componentPath="http://"+this.serverIP.toLowerCase()+":"+this.port+"/current?path="+"//Controller/Components/Path/DataItems/DataItem[@type=\"EXECUTION\" or @type=\"PART_COUNT\"]";
}
@Override
public byte[] httpCall() throws IOException,NumberFormatException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(this.getComponetPath()).build();
Response response;
response = client.newCall(request).execute();
buffer=response.body().bytes();
return buffer;
}
}