Project1

标题: 【不是创意的创意】RM内存自动清理脚本(XP&VX) v 1.00 [打印本页]

作者: 精灵使者    时间: 2011-11-21 00:41
标题: 【不是创意的创意】RM内存自动清理脚本(XP&VX) v 1.00
本帖最后由 精灵使者 于 2013-5-26 21:35 编辑

以前夏娜的10s脚本使用线程的创意启发而来
最近发现RM游戏会占用越来越高的内存。
使用线程原理,定期使用GC.start来清理内存,可以有效的解决吃内存现象。
使用方法:直接插入脚本最上面即可

更新日志:
2011年11月21日 发布原版
参数说明:
GC_FREQ = 1 #清理内存的频率(如果卡机,请调大清理频率,默认1秒整理1次)
GC_TRANSITION = true #场景变换的时候是否立即清理(推荐开启,转移的时候清理掉上次地图的内容,减少卡机)
  1. ############################################################################
  2. # RM内存自动清理脚本(XP&VX) v 1.00
  3. # 作者:精灵使者 创意:夏娜 各种压力的猫君
  4. # 按惯例,此类脚本应该放在最上面,就会自动工作。
  5. # 使用方法:直接插入脚本的最上面即可
  6. # 如果感觉卡机,请修改GC_FREQ
  7. ############################################################################
  8.   #--------------------------------------------------------------------------
  9.   # ● 设定部分
  10.   #--------------------------------------------------------------------------
  11. module GC_CLEAR
  12. GC_FREQ = 1 #清理内存的频率(如果卡机,请调大清理频率,默认1秒整理1次)
  13. GC_TRANSITION = true #场景变换的时候是否立即清理,默认开启
  14. end
  15.   #--------------------------------------------------------------------------
  16.   # ● 创建自动清理线程
  17.   #--------------------------------------------------------------------------
  18. @gc_thread = Thread.new{loop{GC.start;sleep(GC_CLEAR::GC_FREQ)}} if @gc_thread.nil?

  19.   #--------------------------------------------------------------------------
  20.   # ● 场景变换时清理部分
  21.   #--------------------------------------------------------------------------
  22. class << Graphics
  23. alias origin_transition transition unless method_defined? :origin_transition
  24. alias origin_freeze freeze unless method_defined? :origin_freeze

  25. def transition(*args)
  26.   origin_transition(*args)
  27.   GC.start if GC_CLEAR::GC_TRANSITION
  28. end
  29. def freeze
  30.   origin_freeze
  31.   GC.start if GC_CLEAR::GC_TRANSITION
  32. end
  33. end
复制代码

作者: Draks    时间: 2011-11-21 00:54
这个事好东西..大游戏最主要的就是释放内存!~
作者: 精灵使者    时间: 2011-11-21 16:24
本帖最后由 精灵使者 于 2011-11-21 16:26 编辑

测试结果,内存没有像以前那样疯涨了,好像一直都很稳定的样子。
另外这样维持内存的占用的话,小内存配置的机器也不会引起内存意外溢出引起的报错情况。
作者: gamedev0001    时间: 2011-11-21 17:24
提示: 作者被禁止或删除 内容自动屏蔽
作者: yangff    时间: 2011-11-21 19:21
没意义,RUBY187的GC不完善?还有家了这个脚本会让很多东西冲突……
作者: 各种压力的猫君    时间: 2011-11-21 20:08
yangff 发表于 2011-11-21 19:21
没意义,RUBY187的GC不完善?还有家了这个脚本会让很多东西冲突……

好吧,越来越期待VX Ace了……
作者: 第七水螰    时间: 2011-11-22 03:16
這個或許解決了 Ruby 1.8 的 mark-and-sweep GC 算法太過保守的問題,因為默認情況下只有在 Ruby 堆負載過高時 GC 才開始回收。Cache 和 GC 是兩碼事,Cache 是一種緩存優化,GC.start 是開始進行回收失去引用以及只有弱引用內存的過程,當 cache 中的內容沒有被清除時,GC.start 並不能回收 cache 中的內存。上面 @Shy07 說「Cache貌似可以直接扔掉了」不知是出於什麼邏輯?如果沒了 cache,就失去了緩存的優勢。Cache 本身應該有一個良好的 cache 算法,將 cache 塊固定在一個大小,而不是像 RM 這樣無限生長,這是 RM 的缺點。很多程序運行時間越久就越慢就是因為 cache 越來越大,從未被清理。
作者: 精灵使者    时间: 2011-11-22 12:12
本帖最后由 精灵使者 于 2011-11-22 12:14 编辑

不一样,Cache.clear的原始定义(截取至帮助源代码)
  1. def self.clear
  2.       @cache = {}
  3.       GC.start
  4.     end
复制代码
他先清除了索引才调用了GC,这样就满足了GC的“清理失去引用”的条件。
根据8楼的说法,
GC.start 是開始進行回收失去引用以及只有弱引用內存的過程,當 cache 中的內容沒有被清除時,GC.start 並不能回收 cache 中的內存。

于是,正常在Cache里面的东西调用GC的时候,是不会回收的。这样的话可以解决了好多冲突迹象。
P.S.如果把Cache.clear如果替换GC.start的话,才会有副作用呢。
作者: ad1234a    时间: 2011-11-22 13:53
谢谢先,等有空再测试有没有问题
作者: 第七水螰    时间: 2011-11-22 16:52
Shy07 发表于 2011-11-22 09:27
Cahce.clear是整个RGSS2可见部分唯一调用到GC.start的地方,我觉得eb的本意是让用户自己在事件或脚本中手 ...


原來是這個意思,看四樓說「Cache貌似可以直接扔掉了」,我完全理解為「cache 沒有用」了。

我觉得eb的本意是让用户自己在事件或脚本中手动调用Cache.clear [...] 如果要严格控制内存的话,其实可以在Scene.start里用Cache.load_bitmap加载该场景需要的所有位图,Scene.terminate里调用Cache.clear,清空内存并进入下一个场景

你說的很貼近於一種叫 Belady's Algorithm 的 cache 算法,即 cache miss 時總是拋棄未來不會使用的時間最長的內容。然而,這種思路在實踐時幾乎沒有可行性,因為在足夠動態的環境下根本無法確定某個信息是否還會被引用或是會被引用多長時間。手動清空 cache 時,如何能確定清空的位圖在下一個場景中不會被使用?如果這些位圖僅存在於一個場景中,那「在該場景中重複加載這些位圖」的概率能有多高?相比於「在所有場景中反復加載這些位圖」的概率來說自是不算高。按照十一樓提出的方法,「在一個場景中重複加載位圖」的概率越高,cache 的價值才越高,而「別的場景也加載相同位圖」的概率越高,cache 的價值就越低。在編程時或許能確定場景 A 和 場景 B 都用到了位圖 P 而場景 C 沒有用到,但在運行時卻無法預料遊戲到底會過渡到場景 C 還是場景 A、B。 目前 RGSS 的 cache 就像一個巨大的位圖池,無論是在什麼場景使用某個以文件路徑標識的位圖,只要經過了 cache 這層,就永遠只需要加載一次,所以它壓根沒有考慮訪問局部性之類的 cache 問題,它只是默認已經擁有可以快速查閱的表。在一個理想的(無限內存) RAM 計算模型下這是時間上最優的一種設計,但在實踐時卻需要考慮計算機內存的有窮性。

CPU cache 可以看作是 cache 算法的最基本也是最重要的一個應用,不同的硬件採用的 cache miss 處理算法也不同,像拋棄最不常用數據的 LRU,拋棄最常用數據的 MRU,隨機化的 RR 等。RM 理論上完全可以實現這樣的一個 cache。
作者: 禾西    时间: 2011-11-23 14:22
在不確定要使用多少內存的情況下討論緩存管理,有意義嗎(挖鼻孔)Ruby的GC和RM的Cache完全是彼此對立的兩個觀念。
作者: 第七水螰    时间: 2011-11-23 15:16
禾西 发表于 2011-11-23 14:22
在不確定要使用多少內存的情況下討論緩存管理,有意義嗎(挖鼻孔)Ruby的GC和RM的Cache完全是彼此對立的兩 ...

RGSS 默認的 cache 是用了多少內存就有多少緩存,這會導致資枯竭問題。我們討論的是給 cache 塊的大小加一個上限,無論內存的使用量如何,緩存都只能這麼大。
作者: 小湖    时间: 2011-11-29 17:27
有一个疑问……

我使用连续播放图片的方法循环播放一段动画,为了使动画流畅,我事先将图片都显示了一遍放入缓存,这样显示的时候就不会卡了,如果用了这个脚本,每次都要重新加载,岂不是又要开始卡了……
作者: q857539182    时间: 2012-1-5 21:13
好像不太必要,我发现许多人玩完就删了
作者: yangff    时间: 2012-1-5 21:24
= =Cache的管理都能写一篇论文了,涉及到人工智能,期望之类的东西,当然最简单的就是资源表+背包XE
作者: 忧雪の伤    时间: 2012-1-7 17:41
本帖最后由 忧雪の伤 于 2012-1-11 21:09 编辑

有意义?
作者: enghao_lim    时间: 2012-1-8 18:35
我记得……这脚本很久以前美兽就写过了……==''。
用的是RM的方式,自定义释放内存,可以参考。
作者: D_Lohy    时间: 2022-1-3 20:45
VA能用吗




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1