“线程中的异常”;“主要”;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;
    }

}