From 45d90d1e7ba86286e998d1ac4d2cba8e98cd059b Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期一, 12 一月 2026 20:52:30 +0800
Subject: [PATCH] feat: 优化内存

---
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleGpsSegmentMileageServiceImpl.java |  104 +++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 70 insertions(+), 34 deletions(-)

diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleGpsSegmentMileageServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleGpsSegmentMileageServiceImpl.java
index 9936086..a534c6e 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleGpsSegmentMileageServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleGpsSegmentMileageServiceImpl.java
@@ -2,6 +2,7 @@
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 
 import com.ruoyi.common.utils.DateUtils;
@@ -40,6 +41,12 @@
     
     /** 澶╁湴鍥炬壒閲忚矾寰勮鍒扐PI */
     private static final String TIANDITU_ROUTE_API = "http://api.tianditu.gov.cn/drive";
+    
+    /** 绾跨▼瀹夊叏鐨勬棩鏈熸牸寮忓寲鍣� */
+    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+    
+    /** 鍒嗘壒澶勭悊澶у皬锛岄伩鍏嶄竴娆℃�у姞杞借繃澶氭暟鎹� */
+    private static final int BATCH_SIZE = 10;
     
     @Autowired
     private VehicleGpsSegmentMileageMapper segmentMileageMapper;
@@ -118,35 +125,44 @@
                 return 0;
             }
             
-            logger.info("鎵惧埌 {} 杈嗘椿璺冭溅杈嗭紝寮�濮嬮�愯締璁$畻...", vehicleIds.size());
+            logger.info("鎵惧埌 {} 杈嗘椿璺冭溅杈嗭紝寮�濮嬪垎鎵归�愯締璁$畻...", vehicleIds.size());
             
             int successCount = 0;
             int failedCount = 0;
             
-            // 閫愯締璁$畻锛屽寘鍚敊璇鐞嗗拰閲嶈瘯鏈哄埗
-            for (int i = 0; i < vehicleIds.size(); i++) {
-                Long vehicleId = vehicleIds.get(i);
-                try {
-//                    logger.info("姝e湪澶勭悊杞﹁締 {} ({}/{})", vehicleId, i + 1, vehicleIds.size());
-                    
-                    int segmentCount = calculateVehicleSegmentMileage(vehicleId, startTime, endTime);
-                    if (segmentCount > 0) {
-                        successCount++;
-//                        logger.info("杞﹁締 {} 璁$畻鎴愬姛锛岀敓鎴� {} 涓垎娈佃褰�", vehicleId, segmentCount);
-                    } else {
-//                        logger.debug("杞﹁締 {} 鏃犳湁鏂扮殑GPS鍒嗘鏁版嵁", vehicleId);
+            // 鍒嗘壒澶勭悊锛岄伩鍏嶄竴娆℃�у鐞嗚繃澶氭暟鎹鑷村唴瀛樻孩鍑�
+            for (int batchStart = 0; batchStart < vehicleIds.size(); batchStart += BATCH_SIZE) {
+                int batchEnd = Math.min(batchStart + BATCH_SIZE, vehicleIds.size());
+                List<Long> batchVehicleIds = vehicleIds.subList(batchStart, batchEnd);
+                
+                logger.info("澶勭悊鎵规 {}-{}/{}", batchStart + 1, batchEnd, vehicleIds.size());
+                
+                // 閫愯締璁$畻锛屽寘鍚敊璇鐞嗗拰閲嶈瘯鏈哄埗
+                for (int i = 0; i < batchVehicleIds.size(); i++) {
+                    Long vehicleId = batchVehicleIds.get(i);
+                    int overallIndex = batchStart + i;
+                    try {
+                        int segmentCount = calculateVehicleSegmentMileage(vehicleId, startTime, endTime);
+                        if (segmentCount > 0) {
+                            successCount++;
+                        }
+                    } catch (Exception e) {
+                        failedCount++;
+                        logger.error("璁$畻杞﹁締 {} 鐨勫垎娈甸噷绋嬪け璐� ({}/{})", vehicleId, overallIndex + 1, vehicleIds.size(), e);
+                        // 涓嶄腑鏂暣涓壒澶勭悊锛岀户缁鐞嗕笅涓�杈嗚溅
                     }
-                } catch (Exception e) {
-                    failedCount++;
-                    logger.error("璁$畻杞﹁締 {} 鐨勫垎娈甸噷绋嬪け璐� ({}/{})", vehicleId, i + 1, vehicleIds.size(), e);
                     
-                    // 涓嶄腑鏂暣涓壒澶勭悊锛岀户缁鐞嗕笅涓�杈嗚溅
+                    // 姣忓鐞�10杈嗚溅杈撳嚭涓�娆¤繘搴�
+                    if ((overallIndex + 1) % 10 == 0) {
+                        logger.info("鎵归噺璁$畻杩涘害: {}/{}, 鎴愬姛: {}, 澶辫触: {}",
+                                   overallIndex + 1, vehicleIds.size(), successCount, failedCount);
+                    }
                 }
                 
-                // 姣忓鐞�10杈嗚溅杈撳嚭涓�娆¤繘搴�
-                if ((i + 1) % 10 == 0) {
-                    logger.info("鎵归噺璁$畻杩涘害: {}/{}, 鎴愬姛: {}, 澶辫触: {}",
-                               i + 1, vehicleIds.size(), successCount, failedCount);
+                // 鎵规缁撴潫鍚庯紝涓诲姩瑙﹀彂GC寤鸿锛堜笉寮哄埗锛�
+                if (batchEnd < vehicleIds.size()) {
+                    System.gc();
+                    logger.debug("鎵规 {}-{} 澶勭悊瀹屾垚锛屽凡寤鸿JVM鍥炴敹鍐呭瓨", batchStart + 1, batchEnd);
                 }
             }
             
@@ -185,10 +201,15 @@
 
 
             String endTimeStr=DateUtils.formatDate(endTime, DateUtils.YYYY_MM_DD_HH_MM_SS);
-            for (Long vehicleId : vehicleIds) {
-                try {
-                    // 鏌ヨ璇ヨ溅杈嗘湭琚绠楃殑GPS鏁版嵁
-                    List<VehicleGps> uncalculatedGps = vehicleGpsMapper.selectUncalculatedGps(vehicleId, startTimeStr, endTimeStr);
+            // 鍒嗘壒澶勭悊杞﹁締锛岄伩鍏嶅唴瀛樻孩鍑�
+            for (int batchStart = 0; batchStart < vehicleIds.size(); batchStart += BATCH_SIZE) {
+                int batchEnd = Math.min(batchStart + BATCH_SIZE, vehicleIds.size());
+                List<Long> batchVehicleIds = vehicleIds.subList(batchStart, batchEnd);
+                
+                for (Long vehicleId : batchVehicleIds) {
+                    try {
+                        // 鏌ヨ璇ヨ溅杈嗘湭琚绠楃殑GPS鏁版嵁
+                        List<VehicleGps> uncalculatedGps = vehicleGpsMapper.selectUncalculatedGps(vehicleId, startTimeStr, endTimeStr);
                     
                     if (uncalculatedGps == null || uncalculatedGps.isEmpty()) {
                         logger.debug("杞﹁締 {} 娌℃湁鏈绠楃殑GPS鏁版嵁", vehicleId);
@@ -224,12 +245,20 @@
                     int segmentCount = calculateVehicleSegmentMileageWithGpsList(
                         vehicleId, uncalculatedGps, uncalculatedStartTime, uncalculatedEndTime);
                     
-                    if (segmentCount > 0) {
-                        successCount++;
-                        logger.info("杞﹁締 {} 琛ュ伩璁$畻瀹屾垚锛岀敓鎴� {} 涓垎娈佃褰�", vehicleId, segmentCount);
+                        if (segmentCount > 0) {
+                            successCount++;
+                            logger.info("杞﹁締 {} 琛ュ伩璁$畻瀹屾垚锛岀敓鎴� {} 涓垎娈佃褰�", vehicleId, segmentCount);
+                        }
+                    } catch (Exception e) {
+                        logger.error("杞﹁締 {} 琛ュ伩璁$畻澶辫触", vehicleId, e);
                     }
-                } catch (Exception e) {
-                    logger.error("杞﹁締 {} 琛ュ伩璁$畻澶辫触", vehicleId, e);
+                }
+                
+                // 姣忔壒娆$粨鏉熷悗锛屼富鍔ㄥ缓璁瓽C
+                if (batchEnd < vehicleIds.size()) {
+                    uncalculatedGps = null; // 鏄惧紡娓呯┖寮曠敤
+                    System.gc();
+                    logger.debug("琛ュ伩璁$畻鎵规 {}-{} 瀹屾垚锛屽凡寤鸿JVM鍥炴敹鍐呭瓨", batchStart + 1, batchEnd);
                 }
             }
             
@@ -470,7 +499,8 @@
      * 鏀堕泦GPS ID鍒楄〃锛堝寘鎷墠缃偣锛�
      */
     private List<Long> collectGpsIds(List<VehicleGps> segmentGpsList, VehicleGps previousSegmentLastPoint) {
-        List<Long> gpsIdList = new ArrayList<>();
+        // 棰勫垎閰嶅悎鐞嗗閲忥紝鍑忓皯鎵╁寮�閿�
+        List<Long> gpsIdList = new ArrayList<>(segmentGpsList.size() + 1);
         
         // 濡傛灉鏈変笂涓�娈电殑鏈�鍚庝竴涓偣锛屽厛娣诲姞瀹冪殑ID锛堢敤浜庤绠楄法娈佃窛绂伙級
         if (previousSegmentLastPoint != null && previousSegmentLastPoint.getGpsId() != null) {
@@ -822,16 +852,22 @@
 
     /**
      * 瑙f瀽鏃ユ湡鏃堕棿瀛楃涓�
+     * 浣跨敤ThreadLocal鐨凷impleDateFormat锛岄伩鍏嶆瘡娆″垱寤烘柊瀵硅薄
      */
+    private static final ThreadLocal<java.text.SimpleDateFormat> DATE_FORMAT_THREAD_LOCAL = 
+        ThreadLocal.withInitial(() -> {
+            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            sdf.setLenient(false);
+            return sdf;
+        });
+    
     private Date parseDateTime(String dateTimeStr) {
         if (dateTimeStr == null || dateTimeStr.trim().isEmpty()) {
             throw new RuntimeException("鏃ユ湡鏃堕棿瀛楃涓蹭笉鑳戒负绌�");
         }
         
         try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-            sdf.setLenient(false);
-            return sdf.parse(dateTimeStr.trim());
+            return DATE_FORMAT_THREAD_LOCAL.get().parse(dateTimeStr.trim());
         } catch (Exception e) {
             throw new RuntimeException("鏃ユ湡鏃堕棿鏍煎紡閿欒: " + dateTimeStr + ", 搴斾负 yyyy-MM-dd HH:mm:ss", e);
         }

--
Gitblit v1.9.1