遇到OutOfMemoryException时删除一部分List <>

时间:2020-01-18 20:26:24

标签: java

我正在编写一个程序,该程序应该将生成的数据不断推送到List sensorQueue中。副作用是我最终将耗尽内存。发生这种情况时,我想删除列表的一部分,在此示例中,是第一部分,或更旧的一半。我想象如果遇到OutOfMemeryException,我将无法仅使用sensorQueue = sensorQueue.subList((sensorQueue.size() / 2), sensorQueue.size());,所以我来这里寻找答案。

我的代码:

public static void pushSensorData(String sensorData) {
    try {
        sensorQueue.add(parsePacket(sensorData));
    } catch (OutOfMemoryError e) {
        System.out.println("Backlog full");

        //TODO: Cut the sensorQueue in half to make room
    }
    System.out.println(sensorQueue.size());
}

4 个答案:

答案 0 :(得分:1)

那么有没有一种简便的方法来检测即将发生的OutOfMemoryException?

您可以使用以下类似方法来确定最大内存和已用内存。使用这些信息,您可以定义程序中的下一组动作。例如减小其大小或删除一些元素。

final int MEGABYTE = (1024*1024);
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
long maxMemory = heapUsage.getMax() / MEGABYTE;
long usedMemory = heapUsage.getUsed() / MEGABYTE;

希望这会有所帮助!

答案 1 :(得分:1)

import numpy as np import serial import time import sys import cv2 arduino = serial.Serial('COM5', 9600) time.sleep(2) print("Connection to arduino...") face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') cap = cv2.VideoCapture(0) while 1: ret, img = cap.read() img = cv2.flip(img,1) cv2.resizeWindow('img', 500,500) cv2.line(img,(500,250),(0,250),(0,255,0),1) cv2.line(img,(250,0),(250,500),(0,255,0),1) cv2.circle(img, (250, 250), 5, (255, 255, 255), -1) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3) for (x,y,w,h) in faces: cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),5) roi_gray = gray[y:y+h, x:x+w] roi_color = img[y:y+h, x:x+w] arr = {y:y+h, x:x+w} print (arr) print ('X :' +str(x)) print ('Y :'+str(y)) print ('x+w :' +str(x+w)) print ('y+h :' +str(y+h)) xx = int((x+(x+h))/2) yy = int((y+(y+w))/2) print (xx) print (yy) center = (xx,yy) print("Center of Rectangle is :", center) data = "X{0:d}Y{1:d}Z".format(xx, yy) print ("output = '" +data+ "'") # arduino.write(data) arduino.write(data.encode()) cv2.imshow('img',img) k = cv2.waitKey(30) & 0xff if k == 27: break 的问题在于它创建了子列表,将原始列表保存在内存中。但是,subListAbstractList的其他扩展名中有ArrayList会删除当前列表的元素,因此不需要额外的内存。

对于其他List实现,您也可以多次使用removeRange(int fromIndex, int toIndex)来达到相同的目的。

答案 2 :(得分:0)

我认为您的想法存在严重缺陷(抱歉)。

没有OutOfMemoryException,只有OutOfMemory 错误!为什么这很重要?由于错误使应用程序处于不稳定状态,因此我通常不确定该声明,但对于OutOfMemoryError绝对适用。由于无法保证,您将能够赶上它!您可以消耗try-catch块中的所有内存,并且OutOfMemoryError将被抛出在JDK代码中的某个位置。因此,您的捕获毫无意义。

这到底是什么原因呢?您要在列表中显示几则消息?假设您的邮件是1MB。您的堆是1000MB。因此,如果我们停止考虑其他类,则您的堆大小将定义为,您的列表将最多包含1000条消息,对吗?将堆设置得足够大以容纳所需的消息数量,并以更简单的整数形式指定消息数量是否会更容易?而且,如果您的回答为“否”,那么您仍然无法可靠地捕获OutOfMemoryError,因此,我建议您的回答应该为“是”。

如果您确实需要消耗所有可能的资源,则可以按照建议的@fabsas的方式检查内存使用率(%)。但我会采用整数定义-易于管理。您的列表将包含最多N条消息。

答案 3 :(得分:-1)

您可以使用subListArrayList中删除一系列元素:

list.subList(from, to).clear();

from是要删除的范围的第一个索引,而to是最后一个。就您而言,您可以执行以下操作:

list.subList(0, sensorQueue.size() / 2).clear();

请注意,此命令将返回列表。

相关问题