Java内存泄漏-删除垃圾收集

Java内存泄漏-删除垃圾收集,java,heap,heap-dump,Java,Heap,Heap Dump,我已经使用java swing创建了一个应用程序,其中计划了一个计时器,以每秒将RFID读取器中扫描的标签保存到db中,并将其显示为jtable中的活动标签,直到看到它的时间。目前,使用FileWriter,应用程序需要继续运行。 FileWriter=newfilewriter(“text.txt”,true);//除了将标记保存在数据库中之外,还可以将标记保存到文本文件中 我尝试过使用上一篇文章中的答案,比如刷新writer、关闭writer以及在运行时调用垃圾收集器 从图中可以看出,应用程

我已经使用java swing创建了一个应用程序,其中计划了一个计时器,以每秒将RFID读取器中扫描的标签保存到db中,并将其显示为jtable中的活动标签,直到看到它的时间。目前,使用FileWriter,应用程序需要继续运行。 FileWriter=newfilewriter(“text.txt”,true);//除了将标记保存在数据库中之外,还可以将标记保存到文本文件中

我尝试过使用上一篇文章中的答案,比如刷新writer、关闭writer以及在运行时调用垃圾收集器

从图中可以看出,应用程序消耗了1.2gb内存,这才是真正的问题

问题是它在12小时内给了我一个堆空间内存不足错误,并且没有回溯,我无法看到泄漏的来源。有没有办法从JVM中删除收集的垃圾以保持内存空闲

应用程序的行为是,随着时间的推移,对PC机物理内存的消耗越来越大。这会导致堆空间过载

目前正在使用EclipseNeon

来自RfidReader类的代码

    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();
    }
}