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 | 282 ++++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 223 insertions(+), 59 deletions(-)
diff --git a/src/publicway/SerialProtocolParser.java b/src/publicway/SerialProtocolParser.java
index c80bf15..732c879 100644
--- a/src/publicway/SerialProtocolParser.java
+++ b/src/publicway/SerialProtocolParser.java
@@ -1,11 +1,18 @@
package publicway;
+
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
+import chuankou.SerialPortService;
+import chushihua.SlotManager;
+import chushihua.lunxun;
+import dialog.Charulog;
+import dialog.Dingshidialog;
import publicway.ProtocolParser01.ParseResult;
+import xitongshezhi.SystemDebugDialog;
public class SerialProtocolParser {
@@ -21,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();
@@ -40,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;
}
@@ -57,8 +70,6 @@
processorThread = new Thread(this::processPackets, "Serial-Protocol-Parser");
processorThread.setDaemon(true);
processorThread.start();
-
- System.out.println("涓插彛鍗忚瑙f瀽鍣ㄥ凡鍚姩");
}
/**
@@ -93,11 +104,16 @@
}
// 娓呯┖闃熷垪鍜岀紦鍐插尯
+ clearQueues();
+ bufferPosition = 0;
+ }
+
+ /**
+ * 娓呯┖鎵�鏈夐槦鍒楋紝閲婃斁鍐呭瓨
+ */
+ private void clearQueues() {
dataQueue.clear();
batchQueue.clear();
- bufferPosition = 0;
-
- System.out.println("涓插彛鍗忚瑙f瀽鍣ㄥ凡鍋滄");
}
/**
@@ -112,17 +128,39 @@
*/
public void receiveData(byte[] rawData) {
if (!isRunning) {
- System.out.println("璀﹀憡: 涓插彛鍗忚瑙f瀽鍣ㄦ湭鍚姩锛屽拷鐣ユ帴鏀剁殑鏁版嵁");
- return;
+ // 濡傛灉瑙f瀽鍣ㄦ湭杩愯锛岃嚜鍔ㄥ惎鍔�
+ start();
}
if (rawData == null || rawData.length == 0) {
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("璀﹀憡锛氭暟鎹鐞嗛槦鍒楀凡婊★紝宸叉竻绌洪槦鍒楅噸鏂板紑濮�");
}
}
@@ -134,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");
+ }
}
}
@@ -174,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) {
@@ -194,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) {
// 鏁版嵁鍖呬笉瀹屾暣锛岀瓑寰呮洿澶氭暟鎹�
@@ -202,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());
}
// 绉诲姩缂撳啿鍖轰綅缃�
@@ -220,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瀽闃熷垪宸叉弧锛屼涪寮冩渶鑰佹暟鎹寘");
}
}
@@ -239,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;
}
@@ -261,7 +397,7 @@
break;
} catch (Exception e) {
System.err.println("澶勭悊鏁版嵁鍖呮椂鍙戠敓寮傚父: " + e.getMessage());
- e.printStackTrace();
+ // 缁х画杩愯锛屼笉閫�鍑虹嚎绋�
}
}
@@ -272,19 +408,23 @@
* 瑙f瀽鏁版嵁鍖呭苟鏍规嵁鍔熻兘鐮佽皟鐢ㄧ浉搴旀柟娉�
*/
private void parsePacket(byte[] packet) {
+ if (packet == null || packet.length < MIN_PACKET_LENGTH) {
+ return;
+ }
+
try {
+ SerialPortService.getReceivedDataCount();
// 瑙f瀽鍩烘湰瀛楁
byte hostAddress = packet[4]; // 涓绘満鍦板潃
byte slotAddress = packet[5]; // 鍗℃Ы鍦板潃
- byte functionCode = packet[6]; // 鍔熻兘鐮�
-
+ byte functionCode = packet[6]; // 鍔熻兘鐮�
// 鏁版嵁闀垮害 (浠庡崗璁腑璇诲彇)
int dataLength = ((packet[2] & 0xFF) << 8) | (packet[3] & 0xFF);
// 杩斿洖鍊兼暟鎹�
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);
}
@@ -295,43 +435,51 @@
if (returnValue != null) {
// 浣跨敤浼樺寲鐨勫瓧鑺傛暟缁勮В鏋愭柟娉曪紝閬垮厤瀛楃涓茶浆鎹�
ParseResult rst = ProtocolParser01.parseDDCC01Data(packet);
- rst.fuzhi();
- rst.toString();
+ if (rst != null) {
+ rst.fuzhi();
+ if (lunxun.DEBUG_ENABLED) {
+ SystemDebugDialog.appendAsciiData(rst.toString());
+ }
+ }
}
break;
case FUNCTION_51:
// 璋冪敤 ProtocolParser51 澶勭悊鏁版嵁
String hexPacket = bytesToHex(packet);
int result = ProtocolParser51.parse(hexPacket);
+ int slot = slotAddress;
if (result == 1) {
- System.out.println("鍔熻兘鐮� 0x51 - 寮�闂ㄦ帶鍒舵垚鍔�");
+ SlotManager.changgehaska(slot, result);
} else {
- System.out.println("鍔熻兘鐮� 0x51 - 寮�闂ㄦ帶鍒跺け璐ユ垨鎶ユ枃涓嶅悎娉�");
+ 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();
+ // 涓嶆墦鍗板爢鏍堣窡韪紝閬垮厤浜х敓澶ч噺鏃ュ織瀵硅薄
}
}
@@ -339,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));
@@ -377,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);
}
/**
@@ -391,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