扫描二维码关注官方公众号
返回列表
+ 发新帖
查看: 66|回复: 0

[转载发布] 内存泄漏检测脚本V3

[复制链接]
累计送礼:
0 个
累计收礼:
0 个
  • TA的每日心情
    开心
    2025-7-8 01:43
  • 签到天数: 157 天

    连续签到: 2 天

    [LV.7]常住居民III

    2448

    主题

    498

    回帖

    1万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    VIP
    6
    卡币
    13119
    OK点
    16
    推广点
    0
    同能卷
    0
    积分
    16093

    灌水之王

    发表于 4 天前 | 显示全部楼层 |阅读模式
    创意来源:https://rpg.blue/thread-369217-1-1.html
    非常感谢原作者给我提供了思路,但是原本的脚本存在几个问题:数据收集不全,统计方式错误,实际用起来效果并不理想
    所以我请DeepSeek帮我拓展了一下脚本,修复了原本脚本的bug基础上,多了一些花里胡哨但其实没太大用的统计功能
    不要问我为什么是V3

    如何判断发生了内存泄漏:
    在游戏运行一段时间后,明明没干什么特别的事情,游戏突然变得卡顿,而且越来越卡,最后闪退,就很可能是内存泄漏
    如果同时还导致了其他程序的崩溃,那就基本可以确定了

    为什么会发生内存泄漏:
    Rpgmaker中一部分资源是需要使用dispose手动清理的,如果没人清理,即使使用资源的变量已经销毁,也不会释放内存

    如何修复内存泄漏:
    我唯一能给出的建议就是拿着内存泄漏的脚本去问AI

    如何找到发生内存泄漏的脚本:
    RUBY 代码
    [code]#==============================================================================
    # ■ RGSS3 检测内存泄漏V3 by SaiCateDoan
    #------------------------------------------------------------------------------
    # 创意来源:taroxd
    #
    # 使用方法:
    # 1.插入到Main脚本的上面,所有其他脚本的下面
    # 2.正常玩游戏一段时间,进行几次战斗
    # 3.在地图界面按下Alt,建议多按几次
    # 4.重复2-3数次,或重复到游戏卡顿(当然你也可以偷懒)
    # 5.检查未释放对象数量是否异常增长
    #   具体来说,如果有数百个未释放对象,那其实是正常的(来源于脚本的Cache)
    #   但如果未释放对象数量上千,并且还在不断增加,那就很可能发生了内存泄漏
    # 6.在控制台中检查调用栈,寻找其中重复出现的关键词
    # 7.将关键词写到下面的配置中,然后重复以上步骤(可选)
    #   如果想追踪内存泄漏发生的时间,就修改TRIGGER_KEYWORD,然后时刻检查控制台
    #   如果想追踪内存泄漏的速度,就修改STAT_KEYWORDS,检查不同脚本泄漏的数量
    # 8.在脚本编辑器界面按下Ctrl+Shift+F,全局搜索关键词,找到发生内存泄漏的脚本
    # 9.修复它!(如果看不懂,就去问AI吧)
    #------------------------------------------------------------------------------

    # 内存泄露检测系统配置(可修改)
    TRIGGER_KEYWORD = '我是关键词'  # 触发详细调用栈打印的关键词
    STAT_KEYWORDS = [:我是关键词, :我也是关键词]  # 需要统计的关键词列表

    # 扩展Viewport类添加内存释放标记功能
    class Viewport
      def_before(:dispose){@__disposed__ = true}
      def disposed?; @__disposed__; end
    end

    need_dispose = [Bitmap, Sprite, Window, Plane, Tilemap, Viewport]  # 需要监控的对象类型
    $caller_stack_db = {}        # 存储对象创建信息的全局数据库
    not_disposed = []            # 记录当前未释放的对象列表

    # 为所有监控类添加创建追踪功能
    need_dispose.eachdo |klass|
      klass.class_evaldo
        # 追踪initialize操作创建的对象
        def_after(:initialize)do |*|
          record_creation_info(self)
        end

        alias_method :original_clone, :clone
        alias_method :original_dup, :dup

        # 追踪clone操作创建的对象
        def clone
          obj = original_clone
          record_creation_info(obj)
          obj
        end

        # 追踪dup操作创建的对象
        def dup
          obj = original_dup
          record_creation_info(obj)
          obj
        end
      end
    end

    # 记录对象创建时的调用栈和相关信息
    def record_creation_info(obj)
      stack = Kernel.caller
      contains_keyword = stack.any? { |line| line.include?(TRIGGER_KEYWORD)}

      # 触发关键词命中时打印完整调用栈
      if contains_keyword
        puts"[#{TRIGGER_KEYWORD}触发] 对象类型: #{obj.class}"
        puts"完整调用栈:"
        stack.each{ |line| puts"> #{line}"}
        puts"-" * 20
      end

      # 保存对象创建信息到全局数据库
      $caller_stack_db[obj] = {
        :stack => stack,
        :timestamp => Time.now,
        :location => stack.first.to_s
      }
    end

    # 在场景切换时捕获未释放对象
    Scene_Base.class_evaldo
      def_after :terminatedo
        current_not_disposed = []
        need_dispose.eachdo |klass|
          ObjectSpace.each_object(klass)do |obj|
            current_not_disposed
    天天去同能,天天有童年!
    回复 送礼论坛版权

    使用道具 举报

    文明发言,和谐互动
    文明发言,和谐互动
    高级模式
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    幸运抽奖

    社区每日抽奖来袭,快来试试你是欧皇还是非酋~

    立即查看

    聊天机器人
    Loading...

    QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

    GMT+8, 2025-7-24 07:10 , Processed in 0.143201 second(s), 57 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表