java - 线程“主”java.lang.OutOfMemoryError 中的异常:在 http 调用期间无法创建新的本机线程
问题描述
有时我会在运行时遇到以下错误。
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() 返回 byte[] 的缓冲区,否则捕获异常(IOException)。但在这种情况下,我得到 OutOfMemoryError。
@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;
}
}
}
}
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;
}
}
我想抓住 OutOfmemoryError,但我在 StackOverflow 上找到了这个:
如您所知,错误往往表明您的应用程序结束。它通常无法从中恢复,并且应该会导致您的 VM 退出。除了可能在退出之前记录或显示和适当的消息外,不应捕获它们。
我正在尝试找出有关此错误的原因。
解决方案
推荐阅读
- linux - 程序不适用于 crontab(路径问题)
- javascript - 在普通 JavaScript 中从 Node.js 导入类
- asp.net - 替换引导代码后导航栏未固定在顶部
- ruby - 如何大写 attr_accessor
- amazon-web-services - AWS codeBuild:多个输入源到一个输出工件
- python - 查找表类 Python
- excel - 将数据验证列表重置为第一项,方法范围失败
- android - Nexus7 无法加载原生库
- mapbox - 按 ISO 3166-1 alpha-3 国家代码过滤边界瓦片集
- rust - 如何反序列化包含表数组的 TOML 表