From 0bf260dc72b06bb322e939434e02d117dcfc48ff Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 15 四月 2024 17:49:43 +0800
Subject: [PATCH] 10138 内存分析(地图24小时内没有玩家在线则回收py表数据)

---
 PySysDB/生成IpyGameDataPY/IpyGameDataPYTemp.py                                                           |   29 +++++++++
 ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py                                        |   29 +++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py                   |   29 +++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py                      |    1 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py |   38 ++++++++++--
 5 files changed, 120 insertions(+), 6 deletions(-)

diff --git "a/PySysDB/\347\224\237\346\210\220IpyGameDataPY/IpyGameDataPYTemp.py" "b/PySysDB/\347\224\237\346\210\220IpyGameDataPY/IpyGameDataPYTemp.py"
index 4df76c0..0a5516e 100644
--- "a/PySysDB/\347\224\237\346\210\220IpyGameDataPY/IpyGameDataPYTemp.py"
+++ "b/PySysDB/\347\224\237\346\210\220IpyGameDataPY/IpyGameDataPYTemp.py"
@@ -21,6 +21,7 @@
 
 import hashlib
 import os
+import gc
 
 '''表结构定义字典
 {
@@ -60,6 +61,34 @@
         self.IpyDataClear(True)
         return
     
+    def Recycle(self):
+        Log("IPY_DataMgr Recycle")
+        for tableName in Def_IpyTable.keys():
+            if not hasattr(self, "ipy%sLen" % tableName):
+                continue
+            cacheList = getattr(self, "ipy%sCache" % tableName)
+            del cacheList
+            delattr(self, "ipy%sLen" % tableName)
+            delattr(self, "ipy%sCache" % tableName)
+            Log("Recycle IPY_%s" % tableName)
+            
+        del self.fileMD5Dict, self.ipyConfigEx, self.ipyDataIndexMap, self.ipyDataIndexMapEx, self.ipyFuncConfigDict, self.classSizeDict
+        self.fileMD5Dict = {}
+        self.ipyConfigEx = {}
+        self.ipyDataIndexMap = {}
+        self.ipyDataIndexMapEx = {}
+        self.ipyFuncConfigDict = {}
+        self.classSizeDict = {}
+        gc.collect()
+        return
+    
+    def LoadAll(self):
+        ## 加载全部数据,测试内存用,实际应用中不调用
+        for tableName in Def_IpyTable.keys():
+            setattr(self, "ipy%sLen" % tableName, 0)
+        self.IpyDataClear()
+        return
+    
     def IpyDataClear(self, onlyCheck=False):
         Log("IPY_DataMgr Reload... onlyCheck=%s" % onlyCheck)
         if not onlyCheck:
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
index ae6dac9..d8368bb 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
@@ -21,6 +21,7 @@
 
 import hashlib
 import os
+import gc
 
 '''表结构定义字典
 {
@@ -2358,6 +2359,34 @@
         self.IpyDataClear(True)
         return
     
+    def Recycle(self):
+        Log("IPY_DataMgr Recycle")
+        for tableName in Def_IpyTable.keys():
+            if not hasattr(self, "ipy%sLen" % tableName):
+                continue
+            cacheList = getattr(self, "ipy%sCache" % tableName)
+            del cacheList
+            delattr(self, "ipy%sLen" % tableName)
+            delattr(self, "ipy%sCache" % tableName)
+            Log("Recycle IPY_%s" % tableName)
+            
+        del self.fileMD5Dict, self.ipyConfigEx, self.ipyDataIndexMap, self.ipyDataIndexMapEx, self.ipyFuncConfigDict, self.classSizeDict
+        self.fileMD5Dict = {}
+        self.ipyConfigEx = {}
+        self.ipyDataIndexMap = {}
+        self.ipyDataIndexMapEx = {}
+        self.ipyFuncConfigDict = {}
+        self.classSizeDict = {}
+        gc.collect()
+        return
+    
+    def LoadAll(self):
+        ## 加载全部数据,测试内存用,实际应用中不调用
+        for tableName in Def_IpyTable.keys():
+            setattr(self, "ipy%sLen" % tableName, 0)
+        self.IpyDataClear()
+        return
+    
     def IpyDataClear(self, onlyCheck=False):
         Log("IPY_DataMgr Reload... onlyCheck=%s" % onlyCheck)
         if not onlyCheck:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py
index b27cf92..397afc1 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py
@@ -51,6 +51,7 @@
 import PlayerTeam
 import GameMap
 import NPCRealmRefresh
+import IpyGameDataPY
 #---------------------------------------------------------------------
 ## 副本开启
 #  @param gameWorld IPY_GameWorld
@@ -548,7 +549,9 @@
     __ProcessRouteServer(gameWorld, tick)
     
     #每分钟触发
-    __RefreshOnMinute(tick)
+    curTime = GameWorld.GetCurrentTime()
+    __OnMapMinute(curTime, tick)
+    __RefreshOnMinute(curTime, tick)
     #五分钟触发
     __RefreshOnFiveMinute(tick)
     #定时检测关闭超时文件
@@ -752,17 +755,13 @@
 ## 按分钟刷新
 # @param tick
 # @return None
-def __RefreshOnMinute(tick):
+def __RefreshOnMinute(curTime, tick):
     gameWorld = GameWorld.GetGameWorld()
     lastTick = gameWorld.GetTickByType(ChConfig.TYPE_Map_Tick_ProcessMinute)
     tickInterval = ChConfig.TYPE_Map_Tick_Time[ChConfig.TYPE_Map_Tick_ProcessMinute]
     if tick - lastTick < tickInterval:
         return
     gameWorld.SetTickByType(ChConfig.TYPE_Map_Tick_ProcessMinute, tick)
-    
-    curTime = GameWorld.GetCurrentTime()
-    
-    __OnMapMinute(curTime, tick)
     
     playerManager = GameWorld.GetMapCopyPlayerManager()
     for index in xrange(playerManager.GetPlayerCount()):
@@ -780,8 +779,35 @@
         return
     PyGameData.g_mapLastProcess_Minute = curMinute
     PlayerTeam.OnCheckTeamPlayerDisconnectTimeout(tick)
+    
+    __CheckIpyDataRecycle(curTime)
     return
 
+def __CheckIpyDataRecycle(timeNow):
+    ## 检查IpyData数据回收
+    playerCount = GameWorld.GetPlayerManager().OnlineCount()
+    if playerCount:
+        PyGameData.g_ipyDataRecycleCheckTime = 0
+        #GameWorld.DebugLog("地图还有玩家在线! playerCount=%s" % playerCount)
+        return
+    
+    curTime = GameWorld.ChangeDatetimeToNum(timeNow)
+    if not PyGameData.g_ipyDataRecycleCheckTime:
+        PyGameData.g_ipyDataRecycleCheckTime = curTime
+        #GameWorld.DebugLog("地图没有玩家在线")
+        return
+    
+    if PyGameData.g_ipyDataRecycleCheckTime == 1:
+        # 已经回收了
+        #GameWorld.DebugLog("本次已经回收过了")
+        return
+    
+    if curTime - PyGameData.g_ipyDataRecycleCheckTime < 24 * 3600:
+        #GameWorld.DebugLog("还未到达回收时间, passSeconds=%s" % (curTime - PyGameData.g_ipyDataRecycleCheckTime))
+        return
+    PyGameData.g_ipyDataRecycleCheckTime = 1    
+    IpyGameDataPY.IPYData.Recycle()
+    return
 
 ## 整半小时触发 <00和30分钟时触发>
 # @param curPlayer
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index 4572cec..6b3d8ba 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -21,6 +21,7 @@
 
 import hashlib
 import os
+import gc
 
 '''表结构定义字典
 {
@@ -5699,6 +5700,34 @@
         self.IpyDataClear(True)
         return
     
+    def Recycle(self):
+        Log("IPY_DataMgr Recycle")
+        for tableName in Def_IpyTable.keys():
+            if not hasattr(self, "ipy%sLen" % tableName):
+                continue
+            cacheList = getattr(self, "ipy%sCache" % tableName)
+            del cacheList
+            delattr(self, "ipy%sLen" % tableName)
+            delattr(self, "ipy%sCache" % tableName)
+            Log("Recycle IPY_%s" % tableName)
+            
+        del self.fileMD5Dict, self.ipyConfigEx, self.ipyDataIndexMap, self.ipyDataIndexMapEx, self.ipyFuncConfigDict, self.classSizeDict
+        self.fileMD5Dict = {}
+        self.ipyConfigEx = {}
+        self.ipyDataIndexMap = {}
+        self.ipyDataIndexMapEx = {}
+        self.ipyFuncConfigDict = {}
+        self.classSizeDict = {}
+        gc.collect()
+        return
+    
+    def LoadAll(self):
+        ## 加载全部数据,测试内存用,实际应用中不调用
+        for tableName in Def_IpyTable.keys():
+            setattr(self, "ipy%sLen" % tableName, 0)
+        self.IpyDataClear()
+        return
+    
     def IpyDataClear(self, onlyCheck=False):
         Log("IPY_DataMgr Reload... onlyCheck=%s" % onlyCheck)
         if not onlyCheck:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index 943c466..cac03cb 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -21,6 +21,7 @@
 g_commMapLinePlayerCountDict = {} # 常规地图分线人数 {mapID:{lineID:人数, ...}}
 g_needRefreshMapServerState = True # 常规地图分线人数是否有变更需要通知
 g_mapLastProcess_Minute = -1 # 地图上次处理的分钟
+g_ipyDataRecycleCheckTime = 0 # 地图IpyData数据回收检查time
 
 g_playerViewCache = {} # {playerID:{k:v, ...}, ...} # 查看玩家数据缓存
 g_viewCacheCallback = {} # {playerID:any, ...} # 玩家数据缓存回调

--
Gitblit v1.8.0