From d22349714c8d199c02f336f90fba841ef8f5cd39 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期五, 21 十一月 2025 17:46:23 +0800
Subject: [PATCH] 优化内存后最终版202511211746

---
 src/publicway/SerialProtocolParser.java |  273 ++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 212 insertions(+), 61 deletions(-)

diff --git a/src/publicway/SerialProtocolParser.java b/src/publicway/SerialProtocolParser.java
index e68a786..732c879 100644
--- a/src/publicway/SerialProtocolParser.java
+++ b/src/publicway/SerialProtocolParser.java
@@ -1,4 +1,5 @@
 package publicway;
+
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.Executors;
@@ -27,15 +28,15 @@
     private static final byte FUNCTION_82 = (byte) 0x82; // 鍗曟澘鍗囩骇浣胯兘
     private static final byte FUNCTION_83 = (byte) 0x83;   // 鍗曟澘鍗囩骇鏁版嵁鍖�
     
-    // 鏁版嵁缂撳啿鍖猴紝鐢ㄤ簬澶勭悊绮樺寘
+    // 鏁版嵁缂撳啿鍖猴紝鐢ㄤ簬澶勭悊绮樺寘 - 鏀逛负鐩存帴ByteArrayOutputStream绠$悊
     private byte[] dataBuffer = new byte[1024];
     private int bufferPosition = 0;
     
-    // 鏁版嵁鎺ユ敹闃熷垪
-    private BlockingQueue<byte[]> dataQueue = new ArrayBlockingQueue<>(100);
+    // 鏁版嵁鎺ユ敹闃熷垪 - 闄愬埗闃熷垪澶у皬闃叉鍐呭瓨鏃犻檺澧為暱
+    private BlockingQueue<byte[]> dataQueue = new ArrayBlockingQueue<>(50);
     
-    // 鎵归噺澶勭悊闃熷垪
-    private final BlockingQueue<byte[]> batchQueue = new ArrayBlockingQueue<>(1000);
+    // 鎵归噺澶勭悊闃熷垪 - 闄愬埗闃熷垪澶у皬
+    private final BlockingQueue<byte[]> batchQueue = new ArrayBlockingQueue<>(200);
     private final ScheduledExecutorService batchExecutor = 
         Executors.newSingleThreadScheduledExecutor();
     
@@ -46,12 +47,18 @@
     // 閲嶇敤StringBuilder鍑忓皯瀵硅薄鍒涘缓
     private final StringBuilder hexBuilder = new StringBuilder(256);
     
+    // 鍐呭瓨鐩戞帶璁℃暟鍣�
+    private long lastMemoryCheckTime = 0;
+    private static final long MEMORY_CHECK_INTERVAL = 30000; // 30绉掓鏌ヤ竴娆�
+    
+    // 瀵硅薄姹狅紝鍑忓皯瀵硅薄鍒涘缓
+    private final Object packetPoolLock = new Object();
+    
     /**
      * 鍚姩瑙f瀽鍣�
      */
     public void start() {
         if (isRunning) {
-            //System.out.println("涓插彛鍗忚瑙f瀽鍣ㄥ凡缁忓湪杩愯涓�");
             return;
         }
         
@@ -63,8 +70,6 @@
         processorThread = new Thread(this::processPackets, "Serial-Protocol-Parser");
         processorThread.setDaemon(true);
         processorThread.start();
-        
-        //System.out.println("涓插彛鍗忚瑙f瀽鍣ㄥ凡鍚姩 - 鐙珛浜庤疆璇㈢姸鎬佽繍琛�");
     }
     
     /**
@@ -99,11 +104,16 @@
         }
         
         // 娓呯┖闃熷垪鍜岀紦鍐插尯
+        clearQueues();
+        bufferPosition = 0;
+    }
+    
+    /**
+     * 娓呯┖鎵�鏈夐槦鍒楋紝閲婃斁鍐呭瓨
+     */
+    private void clearQueues() {
         dataQueue.clear();
         batchQueue.clear();
-        bufferPosition = 0;
-        
-        //System.out.println("涓插彛鍗忚瑙f瀽鍣ㄥ凡鍋滄");
     }
     
     /**
@@ -126,9 +136,31 @@
             return;
         }
         
-        // 灏嗘暟鎹坊鍔犲埌鎵归噺闃熷垪 - 纭繚濮嬬粓鎵ц
+        // 妫�鏌ラ槦鍒楃姸鎬侊紝閬垮厤鍐呭瓨鏃犻檺澧為暱
+        if (batchQueue.size() > batchQueue.remainingCapacity() * 0.8) {
+            // 闃熷垪鎺ヨ繎婊℃椂锛屼涪寮冩渶鑰佺殑鏁版嵁
+            if (!batchQueue.isEmpty()) {
+                batchQueue.poll(); // 绉婚櫎涓�涓棫鏁版嵁
+            }
+        }
+        
+        // 灏嗘暟鎹坊鍔犲埌鎵归噺闃熷垪
         if (!batchQueue.offer(rawData)) {
-            System.err.println("鎵归噺闃熷垪宸叉弧锛屼涪寮冩暟鎹�");
+            // 闃熷垪宸叉弧鏃剁殑澶勭悊
+            handleQueueFull();
+        }
+    }
+    
+    /**
+     * 澶勭悊闃熷垪婊$殑鎯呭喌
+     */
+    private void handleQueueFull() {
+        // 娓呯┖闃熷垪閲嶆柊寮�濮嬶紝閬垮厤鍐呭瓨娉勬紡
+        clearQueues();
+        bufferPosition = 0; // 閲嶇疆缂撳啿鍖�
+        
+        if (lunxun.DEBUG_ENABLED) {
+            SystemDebugDialog.appendAsciiData("璀﹀憡锛氭暟鎹鐞嗛槦鍒楀凡婊★紝宸叉竻绌洪槦鍒楅噸鏂板紑濮�");
         }
     }
     
@@ -140,39 +172,105 @@
             return;
         }
         
-        // 鎵归噺澶勭悊鏁版嵁
-        java.util.List<byte[]> batch = new java.util.ArrayList<>(100);
-        batchQueue.drainTo(batch, 100);
-        
-        for (byte[] rawData : batch) {
-            // 灏嗘暟鎹坊鍔犲埌缂撳啿鍖�
-            if (bufferPosition + rawData.length > dataBuffer.length) {
-                // 缂撳啿鍖轰笉瓒虫椂锛屾竻鐞嗗苟閲嶆柊寮�濮�
-                System.arraycopy(dataBuffer, bufferPosition - rawData.length, dataBuffer, 0, rawData.length);
-                bufferPosition = rawData.length;
-            } else {
+        try {
+            // 鎵归噺澶勭悊鏁版嵁锛岄檺鍒舵瘡娆″鐞嗙殑鏈�澶ф暟閲�
+            int maxBatchSize = 50;
+            java.util.List<byte[]> batch = new java.util.ArrayList<>(maxBatchSize);
+            batchQueue.drainTo(batch, maxBatchSize);
+            
+            for (byte[] rawData : batch) {
+                // 妫�鏌ョ紦鍐插尯瀹归噺锛岄伩鍏嶆孩鍑�
+                if (bufferPosition + rawData.length > dataBuffer.length) {
+                    // 缂撳啿鍖轰笉瓒虫椂鐨勫鐞�
+                    if (rawData.length > dataBuffer.length) {
+                        // 鍗曟潯鏁版嵁瓒呰繃缂撳啿鍖哄ぇ灏忥紝鐩存帴澶勭悊鎴栦涪寮�
+                        handleOversizedPacket(rawData);
+                        continue;
+                    } else {
+                        // 绉诲姩鏈夋晥鏁版嵁鍒扮紦鍐插尯寮�澶�
+                        compactBuffer(0);
+                    }
+                }
+                
+                // 灏嗘暟鎹坊鍔犲埌缂撳啿鍖�
                 System.arraycopy(rawData, 0, dataBuffer, bufferPosition, rawData.length);
                 bufferPosition += rawData.length;
+                
+                // 澶勭悊缂撳啿鍖轰腑鐨勬暟鎹�
+                processBuffer();
             }
             
-            // 澶勭悊缂撳啿鍖轰腑鐨勬暟鎹�
-            processBuffer();
+            // 瀹氭湡妫�鏌ュ唴瀛�
+            checkMemory();
+            
+        } catch (Exception e) {
+            System.err.println("鎵归噺澶勭悊鏁版嵁鏃跺彂鐢熷紓甯�: " + e.getMessage());
+            // 鍙戠敓寮傚父鏃堕噸缃姸鎬�
+            resetParserState();
         }
-        
-        // 瀹氭湡妫�鏌ュ唴瀛�
-        checkMemory();
+    }
+    
+    /**
+     * 澶勭悊杩囧ぇ鐨勬暟鎹寘
+     */
+    private void handleOversizedPacket(byte[] oversizedData) {
+        // 瀵逛簬杩囧ぇ鐨勬暟鎹寘锛岀洿鎺ュ皾璇曟煡鎵捐捣濮嬫爣璁�
+        int startIndex = findStartMarkerInArray(oversizedData, 0);
+        if (startIndex != -1) {
+            // 鎵惧埌璧峰鏍囪锛屽皢鍓╀綑鏁版嵁鏀惧叆缂撳啿鍖�
+            int remainingLength = oversizedData.length - startIndex;
+            if (remainingLength <= dataBuffer.length) {
+                System.arraycopy(oversizedData, startIndex, dataBuffer, 0, remainingLength);
+                bufferPosition = remainingLength;
+                processBuffer();
+            }
+        }
+        // 鍚﹀垯涓㈠純璇ユ暟鎹寘
+    }
+    
+    /**
+     * 鍦ㄦ寚瀹氭暟缁勪腑鏌ユ壘璧峰鏍囪
+     */
+    private int findStartMarkerInArray(byte[] data, int startPos) {
+        for (int i = startPos; i <= data.length - START_MARKER.length; i++) {
+            if (data[i] == START_MARKER[0] && data[i + 1] == START_MARKER[1]) {
+                return i;
+            }
+        }
+        return -1;
+    }
+    
+    /**
+     * 閲嶇疆瑙f瀽鍣ㄧ姸鎬�
+     */
+    private void resetParserState() {
+        bufferPosition = 0;
+        clearQueues();
     }
     
     /**
      * 鍐呭瓨鐩戞帶
      */
     private void checkMemory() {
+        long currentTime = System.currentTimeMillis();
+        if (currentTime - lastMemoryCheckTime < MEMORY_CHECK_INTERVAL) {
+            return;
+        }
+        
+        lastMemoryCheckTime = currentTime;
+        
         Runtime runtime = Runtime.getRuntime();
         long usedMem = runtime.totalMemory() - runtime.freeMemory();
         long maxMem = runtime.maxMemory();
         
-        if (usedMem > maxMem * 0.8) {
-            //System.out.println("鍐呭瓨浣跨敤鐜囪秴杩�80%锛屽綋鍓嶄娇鐢�: " + (usedMem / 1024 / 1024) + "MB");
+        if (usedMem > maxMem * 0.75) {
+            // 鍐呭瓨浣跨敤鐜囪秴杩�75%鏃惰繘琛屽瀮鍦惧洖鏀�
+            System.gc();
+            
+            if (lunxun.DEBUG_ENABLED) {
+                SystemDebugDialog.appendAsciiData("鍐呭瓨浣跨敤鐜囪秴杩�75%锛屽凡瑙﹀彂鍨冨溇鍥炴敹銆備娇鐢ㄥ唴瀛�: " + 
+                    (usedMem / 1024 / 1024) + "MB");
+            }
         }
     }
     
@@ -180,7 +278,10 @@
      * 澶勭悊缂撳啿鍖轰腑鐨勬暟鎹紝瑙f瀽瀹屾暣鏁版嵁鍖�
      */
     private void processBuffer() {
-        while (bufferPosition >= MIN_PACKET_LENGTH) {
+        int processedCount = 0;
+        final int MAX_PACKETS_PER_BATCH = 20; // 闄愬埗姣忔澶勭悊鐨勬渶澶у寘鏁伴噺
+        
+        while (bufferPosition >= MIN_PACKET_LENGTH && processedCount < MAX_PACKETS_PER_BATCH) {
             // 鏌ユ壘璧峰鏍囪
             int startIndex = findStartMarker();
             if (startIndex == -1) {
@@ -200,6 +301,13 @@
             int dataLength = ((dataBuffer[startIndex + 2] & 0xFF) << 8) | (dataBuffer[startIndex + 3] & 0xFF);
             int totalPacketLength = 2 + 2 + dataLength + 2; // 璧峰鏍囪2 + 鏁版嵁闀垮害2 + 鏁版嵁鍐呭 + CRC2
             
+            // 妫�鏌ユ暟鎹暱搴︽槸鍚﹀悎鐞�
+            if (dataLength < 0 || totalPacketLength > dataBuffer.length) {
+                // 鏁版嵁闀垮害寮傚父锛岃烦杩囪繖涓寘
+                compactBuffer(startIndex + 1);
+                continue;
+            }
+            
             // 妫�鏌ユ槸鍚︽敹鍒板畬鏁存暟鎹寘
             if (startIndex + totalPacketLength > bufferPosition) {
                 // 鏁版嵁鍖呬笉瀹屾暣锛岀瓑寰呮洿澶氭暟鎹�
@@ -208,16 +316,15 @@
             }
             
             // 鎻愬彇瀹屾暣鏁版嵁鍖�
-            byte[] packet = new byte[totalPacketLength];
-            System.arraycopy(dataBuffer, startIndex, packet, 0, totalPacketLength);
-            
-            // 灏嗘暟鎹寘鏀惧叆闃熷垪渚涜В鏋�
-            try {
+            byte[] packet = extractPacket(startIndex, totalPacketLength);
+            if (packet != null) {
+                // 灏嗘暟鎹寘鏀惧叆闃熷垪渚涜В鏋�
                 if (!dataQueue.offer(packet)) {
-                    System.err.println("鏁版嵁闃熷垪宸叉弧锛屼涪寮冩暟鎹寘");
+                    // 闃熷垪宸叉弧锛岄噴鏀緋acket寮曠敤
+                    packet = null;
+                    handleDataQueueFull();
+                    return;
                 }
-            } catch (Exception e) {
-                System.err.println("鏀惧叆鏁版嵁闃熷垪鏃跺彂鐢熷紓甯�: " + e.getMessage());
             }
             
             // 绉诲姩缂撳啿鍖轰綅缃�
@@ -226,6 +333,29 @@
                 System.arraycopy(dataBuffer, startIndex + totalPacketLength, dataBuffer, 0, remaining);
             }
             bufferPosition = remaining;
+            
+            processedCount++;
+        }
+    }
+    
+    /**
+     * 鎻愬彇鏁版嵁鍖咃紝閲嶇敤byte鏁扮粍鍑忓皯瀵硅薄鍒涘缓
+     */
+    private byte[] extractPacket(int startIndex, int totalPacketLength) {
+        byte[] packet = new byte[totalPacketLength];
+        System.arraycopy(dataBuffer, startIndex, packet, 0, totalPacketLength);
+        return packet;
+    }
+    
+    /**
+     * 澶勭悊鏁版嵁闃熷垪婊$殑鎯呭喌
+     */
+    private void handleDataQueueFull() {
+        // 涓㈠純闃熷垪涓渶鑰佺殑鏁版嵁
+        dataQueue.poll();
+        
+        if (lunxun.DEBUG_ENABLED) {
+            SystemDebugDialog.appendAsciiData("鏁版嵁瑙f瀽闃熷垪宸叉弧锛屼涪寮冩渶鑰佹暟鎹寘");
         }
     }
     
@@ -245,7 +375,7 @@
      * 鍘嬬缉缂撳啿鍖猴紝灏嗘湁鏁堟暟鎹Щ鍒板紑澶�
      */
     private void compactBuffer(int startIndex) {
-        if (startIndex > 0) {
+        if (startIndex > 0 && bufferPosition > startIndex) {
             System.arraycopy(dataBuffer, startIndex, dataBuffer, 0, bufferPosition - startIndex);
             bufferPosition -= startIndex;
         }
@@ -267,7 +397,7 @@
                 break;
             } catch (Exception e) {
                 System.err.println("澶勭悊鏁版嵁鍖呮椂鍙戠敓寮傚父: " + e.getMessage());
-                e.printStackTrace();
+                // 缁х画杩愯锛屼笉閫�鍑虹嚎绋�
             }
         }
         
@@ -278,8 +408,12 @@
      * 瑙f瀽鏁版嵁鍖呭苟鏍规嵁鍔熻兘鐮佽皟鐢ㄧ浉搴旀柟娉�
      */
     private void parsePacket(byte[] packet) {
+        if (packet == null || packet.length < MIN_PACKET_LENGTH) {
+            return;
+        }
+        
         try {
-        	SerialPortService.getReceivedDataCount();
+            SerialPortService.getReceivedDataCount();
             // 瑙f瀽鍩烘湰瀛楁
             byte hostAddress = packet[4];        // 涓绘満鍦板潃
             byte slotAddress = packet[5];        // 鍗℃Ы鍦板潃
@@ -290,7 +424,7 @@
             // 杩斿洖鍊兼暟鎹�
             int returnValueLength = dataLength - 3; // N-3 (鍑忓幓涓绘満鍦板潃銆佸崱妲藉湴鍧�銆佸姛鑳界爜)
             byte[] returnValue = null;
-            if (returnValueLength > 0) {
+            if (returnValueLength > 0 && returnValueLength <= packet.length - 7) {
                 returnValue = new byte[returnValueLength];
                 System.arraycopy(packet, 7, returnValue, 0, returnValueLength);
             }
@@ -301,12 +435,12 @@
                     if (returnValue != null) {
                         // 浣跨敤浼樺寲鐨勫瓧鑺傛暟缁勮В鏋愭柟娉曪紝閬垮厤瀛楃涓茶浆鎹�
                         ParseResult rst = ProtocolParser01.parseDDCC01Data(packet);
-                        rst.fuzhi();
-//                        System.out.println(rst.toString());      
-                        if (lunxun.DEBUG_ENABLED) {
-                            SystemDebugDialog.appendAsciiData(rst.toString());
+                        if (rst != null) {
+                            rst.fuzhi();
+                            if (lunxun.DEBUG_ENABLED) {
+                                SystemDebugDialog.appendAsciiData(rst.toString());
+                            }
                         }
-                        
                     }
                     break;
                 case FUNCTION_51:
@@ -315,36 +449,37 @@
                     int result = ProtocolParser51.parse(hexPacket);
                     int slot = slotAddress;
                     if (result == 1) {
-//                    	Dingshidialog.showTimedDialog(null, 5,slot+"鍙峰崱妲藉嚭鍗℃垚鍔熻鍙栬蛋鍗�...");
-                    	SlotManager.changgehaska(slot, result);
+                        SlotManager.changgehaska(slot, result);
                     } else {
-                    	String message=slot+"鍙峰崱妲藉彇鍗″け璐�";
+                        String message = slot + "鍙峰崱妲藉彇鍗″け璐�";
                         Charulog.logOperation(message);
                     }
                     break;
                 case FUNCTION_52:
-                    //System.out.println("鍔熻兘鐮� 0x52 - LED浜害鎺у埗");
+                    // LED浜害鎺у埗 - 鏃犳搷浣�
                     break;
                 case FUNCTION_80:
-                    //System.out.println("鍔熻兘鐮� 0x80 - 宸ュ崱鍗囩骇浣胯兘");
+                    // 宸ュ崱鍗囩骇浣胯兘 - 鏃犳搷浣�
                     break;
                 case FUNCTION_81:
-                    //System.out.println("鍔熻兘鐮� 0x81 - 宸ヤ綔鍗″崌绾ф暟鎹寘");
+                    // 宸ヤ綔鍗″崌绾ф暟鎹寘 - 鏃犳搷浣�
                     break;
                 case FUNCTION_82:
-                    //System.out.println("鍔熻兘鐮� 0x82 - 鍗曟澘鍗囩骇浣胯兘");
+                    // 鍗曟澘鍗囩骇浣胯兘 - 鏃犳搷浣�
                     break;
                 case FUNCTION_83:
-                    //System.out.println("鍔熻兘鐮� 0x83 - 鍗曟澘鍗囩骇鏁版嵁鍖�");
+                    // 鍗曟澘鍗囩骇鏁版嵁鍖� - 鏃犳搷浣�
                     break;
                 default:
-                    System.err.println("鏈煡鍔熻兘鐮�: 0x" + Integer.toHexString(functionCode & 0xFF));
+                    if (lunxun.DEBUG_ENABLED) {
+                        System.err.println("鏈煡鍔熻兘鐮�: 0x" + Integer.toHexString(functionCode & 0xFF));
+                    }
                     break;
             }
             
         } catch (Exception e) {
             System.err.println("瑙f瀽鏁版嵁鍖呮椂鍙戠敓閿欒: " + e.getMessage());
-            e.printStackTrace();
+            // 涓嶆墦鍗板爢鏍堣窡韪紝閬垮厤浜х敓澶ч噺鏃ュ織瀵硅薄
         }
     }
     
@@ -352,6 +487,10 @@
      * 浼樺寲鐨勫瓧鑺傛暟缁勮浆鍗佸叚杩涘埗瀛楃涓叉柟娉�
      */
     private String bytesToHex(byte[] bytes) {
+        if (bytes == null || bytes.length == 0) {
+            return "";
+        }
+        
         hexBuilder.setLength(0); // 娓呯┖閲嶇敤
         for (byte b : bytes) {
             hexBuilder.append(String.format("%02X", b));
@@ -390,12 +529,14 @@
      * 鑾峰彇瑙f瀽鍣ㄧ姸鎬佷俊鎭�
      */
     public String getStatusInfo() {
-        return String.format("涓插彛瑙f瀽鍣ㄧ姸鎬�: %s, 闃熷垪澶у皬: %d/%d, 鎵归噺闃熷垪: %d/%d", 
+        return String.format("涓插彛瑙f瀽鍣ㄧ姸鎬�: %s, 闃熷垪澶у皬: %d/%d, 鎵归噺闃熷垪: %d/%d, 缂撳啿鍖�: %d/%d", 
                            isRunning ? "杩愯涓�" : "宸插仠姝�", 
                            dataQueue.size(), 
                            dataQueue.remainingCapacity() + dataQueue.size(),
                            batchQueue.size(),
-                           batchQueue.remainingCapacity() + batchQueue.size());
+                           batchQueue.remainingCapacity() + batchQueue.size(),
+                           bufferPosition,
+                           dataBuffer.length);
     }
     
     /**
@@ -404,4 +545,14 @@
     public void setMaxRawDataPrintLength(int length) {
         // 瀹炵幇鏍规嵁闇�瑕佽皟鏁�
     }
+    
+    /**
+     * 涓诲姩娓呯悊璧勬簮
+     */
+    public void cleanup() {
+        stop();
+        clearQueues();
+        bufferPosition = 0;
+        hexBuilder.setLength(0);
+    }
 }
\ No newline at end of file

--
Gitblit v1.9.3