我正在编写一个程序,该程序应该将生成的数据不断推送到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());
}
答案 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
的问题在于它创建了子列表,将原始列表保存在内存中。但是,subList
或AbstractList的其他扩展名中有ArrayList
会删除当前列表的元素,因此不需要额外的内存。
对于其他List实现,您也可以多次使用removeRange(int fromIndex, int toIndex)
来达到相同的目的。
答案 2 :(得分:0)
我认为您的想法存在严重缺陷(抱歉)。
没有OutOfMemoryException,只有OutOfMemory 错误!为什么这很重要?由于错误使应用程序处于不稳定状态,因此我通常不确定该声明,但对于OutOfMemoryError绝对适用。由于无法保证,您将能够赶上它!您可以消耗try-catch块中的所有内存,并且OutOfMemoryError将被抛出在JDK代码中的某个位置。因此,您的捕获毫无意义。
这到底是什么原因呢?您要在列表中显示几则消息?假设您的邮件是1MB。您的堆是1000MB。因此,如果我们停止考虑其他类,则您的堆大小将定义为,您的列表将最多包含1000条消息,对吗?将堆设置得足够大以容纳所需的消息数量,并以更简单的整数形式指定消息数量是否会更容易?而且,如果您的回答为“否”,那么您仍然无法可靠地捕获OutOfMemoryError,因此,我建议您的回答应该为“是”。
如果您确实需要消耗所有可能的资源,则可以按照建议的@fabsas的方式检查内存使用率(%)。但我会采用整数定义-易于管理。您的列表将包含最多N条消息。
答案 3 :(得分:-1)
您可以使用subList
从ArrayList
中删除一系列元素:
list.subList(from, to).clear();
from
是要删除的范围的第一个索引,而to
是最后一个。就您而言,您可以执行以下操作:
list.subList(0, sensorQueue.size() / 2).clear();
请注意,此命令将返回列表。