Java内存泄漏-删除垃圾收集
我已经使用java swing创建了一个应用程序,其中计划了一个计时器,以每秒将RFID读取器中扫描的标签保存到db中,并将其显示为jtable中的活动标签,直到看到它的时间。目前,使用FileWriter,应用程序需要继续运行。 FileWriter=newfilewriter(“text.txt”,true);//除了将标记保存在数据库中之外,还可以将标记保存到文本文件中 我尝试过使用上一篇文章中的答案,比如刷新writer、关闭writer以及在运行时调用垃圾收集器 从图中可以看出,应用程序消耗了1.2gb内存,这才是真正的问题 问题是它在12小时内给了我一个堆空间内存不足错误,并且没有回溯,我无法看到泄漏的来源。有没有办法从JVM中删除收集的垃圾以保持内存空闲 应用程序的行为是,随着时间的推移,对PC机物理内存的消耗越来越大。这会导致堆空间过载 目前正在使用EclipseNeon 来自RfidReader类的代码Java内存泄漏-删除垃圾收集,java,heap,heap-dump,Java,Heap,Heap Dump,我已经使用java swing创建了一个应用程序,其中计划了一个计时器,以每秒将RFID读取器中扫描的标签保存到db中,并将其显示为jtable中的活动标签,直到看到它的时间。目前,使用FileWriter,应用程序需要继续运行。 FileWriter=newfilewriter(“text.txt”,true);//除了将标记保存在数据库中之外,还可以将标记保存到文本文件中 我尝试过使用上一篇文章中的答案,比如刷新writer、关闭writer以及在运行时调用垃圾收集器 从图中可以看出,应用程
public class RfidTagSearch{
public String getReaderResult() {return inputReader.toString();}
public String getResult() {return res;}
public String getTags() {return strBuff.toString();}
public String getStrResult() {return strResult.toString();}
public ArrayList<String> getSeenKey(){
ArrayList<String> temp = rfidKey;
rfidKey.clear();
return temp;
}
public void connectToReader(String host, int _port) throws Exception{
hostName = host;
port = _port;
myReader.Dispose();
myReader = new RFIDReader();
myReader.setHostName(hostName);
myReader.setPort(port);
try {
myReader.connect();
myReader.Events.setInventoryStartEvent(true);
myReader.Events.setInventoryStopEvent(true);
myReader.Events.setAccessStartEvent(true);
myReader.Events.setAccessStopEvent(true);
myReader.Events.setAntennaEvent(true);
myReader.Events.setGPIEvent(true);
myReader.Events.setBufferFullEvent(true);
myReader.Events.setBufferFullWarningEvent(true);
myReader.Events.setReaderDisconnectEvent(true);
myReader.Events.setReaderExceptionEvent(true);
myReader.Events.setTagReadEvent(true);
myReader.Events.setAttachTagDataWithReadEvent(false);
TagStorageSettings tagStorageSettings = myReader.Config.getTagStorageSettings();
tagStorageSettings.discardTagsOnInventoryStop(true);
myReader.Config.setTagStorageSettings(tagStorageSettings);
myReader.Events.addEventsListener(new EventsHandler());
isConnected = true;
strResult.append("Connected to " + hostName + "\n");
//strResult.append(API_SUCCESS);
myReader.Config.setTraceLevel(TRACE_LEVEL.TRACE_LEVEL_ERROR);
res = "Success";
} catch (InvalidUsageException ex)
{
strResult.append(PARAM_ERROR + ex.getVendorMessage());
} catch (OperationFailureException ex) {
strResult.append(ex.getStatusDescription() +
ex.getVendorMessage());
}
}
public Boolean isConnected() { return isConnected;}
public void disconnectToReader() throws Exception{
myReader = new RFIDReader();
}
private Boolean isScanning = false;
// start Scanning
public void startScanning() throws InterruptedException,InvalidUsageException,OperationFailureException
{
tagStore.clear();
myReader.Actions.Inventory.perform();
}
public void stopScanning() throws InvalidUsageException, OperationFailureException, InterruptedException{
myReader.Actions.Inventory.stop();
}
String saveDir = "", fileName = "";
public void setSaveDirectory(String value) {
saveDir = value;
}
public long getTagCount() {return totalTags;}
// getting current time and date
public String getDateandTime(){
String res = "";
LocalDateTime myDateObj = LocalDateTime.now();
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDate = myDateObj.format(myFormatObj);
res = formattedDate.toString();
return res;
}
int Switch=0,tempVal=0;
public void setTimer(int minute){
long timeInterval = minute * 60 * 1000;
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
Switch++;
}
}, timeInterval, timeInterval);
}
FileWriter fw;
public class EventsHandler implements RfidEventsListener
{
public EventsHandler()
{
fileName = getDateandTime().replace(":", "-") + ".txt";
}
public void eventReadNotify(RfidReadEvents e){
TagDataArray oTagDataArray = myReader.Actions.getReadTagsEx(1000);
myTags = oTagDataArray.getTags();
try {
fw = new FileWriter(saveDir + "/" + fileName,true);
if (myTags != null)
{
for (int index = 0; index < oTagDataArray.getLength(); index++)
{
if (Switch != tempVal) {
tempVal = Switch;
fileName = getDateandTime().replace(":", "-") + ".txt";
fw = new FileWriter(saveDir + "/" + fileName,true);
}
TagData tag = myTags[index];
String key = tag.getTagID();
String subStr = key.substring(key.length() - 6,key.length());
res = mysql.validateRfidKey(subStr);
if (res.equals("Found")){
res = mysql.updateLastSeen(subStr, getDateandTime());
res = mysql.searchAllData(subStr);
if (res.equals("Found")){
if (mysql.getStatus().equals("1")){
rfidKey.add(subStr);
key = key + " - THIS KEY IS FOUND";
}
}
}
else{
res = mysql.searchUnregisteredKey(subStr);
if (res.equals("Found")) {
key = key + " - UNREGISTERED KEY";
}
else {
key = key + " -NEW UNREGISTERED KEY";
res = mysql.saveUnregisteredKey(subStr, getDateandTime());
}
}
fw.write(getDateandTime() +" : "+ key + System.getProperty( "line.separator")); // THE DATA OF THE READER WILL BE INPUTTED HERE AND WILL BE SAVE TO LOCAL PC
totalTags++;
}
}
else {
fw.write("empty tag");;
}
fw.flush();
fw.close();
System.gc();
Runtime.getRuntime().gc();
} catch (IOException e1) {
// TODO Auto-generated catch block
System.out.print("Error in RFID tag search");
e1.printStackTrace();
}
}
// Status Event Notification
public void eventStatusNotify(RfidStatusEvents e) {
System.out.println("Status Notification " + e.StatusEventData.getStatusEventType());
}
}
}
如果应用程序超过JVM分配的内存量,则会发生内存不足(OOM)错误
您可以通过分配更多内存来启动JVM。JVM命令-Xmx
指定最大堆大小
java -Xmx1024m -jar your-application.jar
如果您的FileWriter没有缓冲,则会使写入过程非常缓慢。因此,您应该将FileWriter包装在BufferedWriter流中
PrintWriter out = null;
try {
out = new PrintWriter(new BufferedWriter(new FileWriter("text.txt", true)));
out.println("the text you want to append");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
计算机系统上最昂贵的操作之一是IO,与其连续写入文件,不如在标签达到一定大小时将其存储在StringBuffer中,然后再将其写入文件。如果没有看到代码,就无法提供帮助。请发布一条说明问题的说明。并使其保持最小值。注意:垃圾收集器已经从JVM中删除了收集的垃圾。如果您从内存错误中获得堆空间,则意味着垃圾收集器无法收集任何内容。也就是说,所有堆空间都被可访问的对象占用。OOME会抛出几种类型的错误,例如堆空间耗尽或达到文件描述符限制。首先了解您遇到的OOME风格,然后寻找修复方法。我已经更新了帖子,插入了阅读器和Jtble使用的图像和代码。垃圾收集器在Rfid中运行Reader@AnimotoDito对gc的调用不会强制gc,它不会立即生效。内存泄漏可能导致OOME。除非发布完整的代码和日志跟踪,否则无法找到程序泄漏的原因。请不要隐藏捕获的异常。请不要试图智取系统。BufferedWrite对您来说已经足够了,不需要使用另一个StringBuffer层我不建议隐藏捕获的异常我只是跳过代码,我已经编辑了代码段以抛出异常。
java -Xmx1024m -jar your-application.jar
PrintWriter out = null;
try {
out = new PrintWriter(new BufferedWriter(new FileWriter("text.txt", true)));
out.println("the text you want to append");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}