首页 > 解决方案 > 线程“主”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 退出。除了可能在退出之前记录或显示和适当的消息外,不应捕获它们。

我正在尝试找出有关此错误的原因。

标签: javaout-of-memory

解决方案


推荐阅读