Project1

标题: 【Image Cache问题】感觉MV游戏跑着跑着内存会越来越大 [打印本页]

作者: trentswd    时间: 2015-12-27 01:10
标题: 【Image Cache问题】感觉MV游戏跑着跑着内存会越来越大
本帖最后由 trentswd 于 2015-12-27 01:12 编辑

这个问题很早就看RPGMAKERWEB上讨论过了,当时没仔细看
最近看了看,惊了
RMMV的Image Load的实现是这样的:
JAVASCRIPT 代码复制
  1. ImageManager.loadNormalBitmap = function(path, hue) {
  2.     var key = path + ':' + hue;
  3.     if (!this._cache[key]) {
  4.         var bitmap = Bitmap.load(path);
  5.         bitmap.addLoadListener(function() {
  6.             bitmap.rotateHue(hue);
  7.         });
  8.         this._cache[key] = bitmap;
  9.     }
  10.     return this._cache[key];
  11. };
  12.  
  13. ImageManager.clear = function() {
  14.     this._cache = {};
  15. };

按照这个用法,每个载入的图片都会保存在ImageManager._cache中,根本不会释放,也没有什么先入先出、最少使用先出之类的清空方法
只有使用ImageManager.clear才会清空,然而默认脚本里面压根就没调用过这个方法

理论上游戏很大的话,随着游戏时间的增加,最后会把所有的图片都读到内存里面去?还是说Html5的Image会自动释放?
作者: 西姐    时间: 2015-12-27 01:18
我发现每天第一次开游戏很慢,然后就快了,应该是电脑关了就消了吧
作者: 汪汪    时间: 2015-12-27 09:53
于是该怎么办呢?
添加一个预加载和过多处理的方法吗?
作者: doranikofu    时间: 2015-12-27 11:17
搬运一个插件 还没研究细节
其实要能做的只能一点在事件里面调用的话应该很方便
做远景地图的话 离开一个区域可以在传送点加入清缓存代码

JAVASCRIPT 代码复制
  1. //=============================================================================
  2.     // Cache Manager
  3.     // by Shaz
  4.     // Last Updated: 2015.10.30
  5.     //=============================================================================
  6.  
  7.     /*:
  8.      * @plugindesc Selectively clear the image cache for memory usage improvements
  9.      * @author Shaz
  10.      *
  11.      * @param Mobile only
  12.      * @desc Cache management only runs on mobile platforms (N to run on all platforms)
  13.      * @default Y
  14.      *
  15.      * @param --------------------------------------------
  16.      *
  17.      * @param Clear All
  18.      * @desc Clears all cached images except System (if Y, ignore remaining parameters)
  19.      * @default Y
  20.      *
  21.      * @param Clear Animations
  22.      * @desc Clear Animation images
  23.      * @default Y
  24.      *
  25.      * @param Clear Battlebacks
  26.      * @desc Clear Battleback images
  27.      * @default Y
  28.      *
  29.      * @param Clear Battlers
  30.      * @desc Clear Battler images
  31.      * @default Y
  32.      *
  33.      * @param Clear Characters
  34.      * @desc Clear Character images
  35.      * @default Y
  36.      *
  37.      * @param Clear Faces
  38.      * @desc Clear Face images
  39.      * @default Y
  40.      *
  41.      * @param Clear Parallaxes
  42.      * @desc Clear Parallax images
  43.      * @default Y
  44.      *
  45.      * @param Clear Pictures
  46.      * @desc Clear Picture images
  47.      * @default Y
  48.      *
  49.      * @param Clear System
  50.      * @desc Clear System images (not recommended)
  51.      * @default N
  52.      *
  53.      * @param Clear Tilesets
  54.      * @desc Clear Tileset images
  55.      * @default Y
  56.      *
  57.      * @param Clear Titles
  58.      * @desc Clear Title images
  59.      * @default Y
  60.      *
  61.      * @param Custom Images
  62.      * @desc List custom image paths to clear, separated by ; (img/fogs; img/busts)
  63.      * @default
  64.      *
  65.      * @help This plugin does not provide plugin commands.
  66.      *
  67.      * This plugin allows you to specify how often the image cache should be
  68.      * cleared, and what kind of images should be cleared.  This can be used
  69.      * to improve memory usage on low-memory platforms, but will also result
  70.      * in more frequent loading delays.
  71.      *
  72.      * If not using the 'clear all' default option, and you have plugins that
  73.      * use their own custom image paths, list those paths in the Custom Images
  74.      * parameter to clear any images cached from those locations.
  75.      *
  76.      */
  77.  
  78.     (function() {
  79.       var params = PluginManager.parameters('CacheManager');
  80.       var mobile = (params['Mobile only'] || 'Y').toUpperCase().substring(0,1) === 'Y';
  81.       var clearAll = (params['Clear All'] || 'Y').toUpperCase().substring(0,1) === 'Y';
  82.       if (!clearAll) {
  83.         pathsToClear = [];
  84.         if ((params['Clear Animations'] || 'Y').toUpperCase().substring(0,1) === 'Y')
  85.           pathsToClear.push('img/animations');
  86.         if ((params['Clear Battlebacks'] || 'Y').toUpperCase().substring(0,1) === 'Y')
  87.           pathsToClear.push('img/battlebacks1', 'img/battlebacks2');
  88.         if ((params['Clear Battlers'] || 'Y').toUpperCase().substring(0,1) === 'Y')
  89.           pathsToClear.push('img/enemies', 'img/sv-actors', 'img/sv-enemies');
  90.         if ((params['Clear Characters'] || 'Y').toUpperCase().substring(0,1) === 'Y')
  91.           pathsToClear.push('img/characters');
  92.         if ((params['Clear Faces'] || 'Y').toUpperCase().substring(0,1) === 'Y')
  93.           pathsToClear.push('img/faces');
  94.         if ((params['Clear Parallaxes'] || 'Y').toUpperCase().substring(0,1) === 'Y')
  95.           pathsToClear.push('img/parallaxes');
  96.         if ((params['Clear Pictures'] || 'Y').toUpperCase().substring(0,1) === 'Y')
  97.           pathsToClear.push('img/pictures');
  98.         if ((params['Clear System'] || 'N').toUpperCase().substring(0,1) === 'Y')
  99.           pathsToClear.push('img/system');
  100.         if ((params['Clear Tilesets'] || 'Y').toUpperCase().substring(0,1) === 'Y')
  101.           pathsToClear.push('img/tilesets');
  102.         if ((params['Clear Titles'] || 'Y').toUpperCase().substring(0,1) === 'Y')
  103.           pathsToClear.push('img/titles1', 'img/titles2');
  104.         (params['Custom Images'] || '').split(';').forEach(function(path) { if (path) pathsToClear.push(path.trim()) }.bind(this));
  105.       }
  106.  
  107.       ImageManager.clear = function() {
  108.         for (image in this._cache) {
  109.           if (clearAll && image.indexOf('img/system') === -1)
  110.             this.removeFromCache(image);
  111.           else if (!clearAll && pathsToClear.some(function(path) { return image.indexOf(path) > -1}.bind(this)))
  112.             this.removeFromCache(image);
  113.         }
  114.       };
  115.  
  116.       ImageManager.removeFromCache = function(image) {
  117.         if (image !== 'null') {
  118.           if (this._cache.hasOwnProperty(image) && this._cache[image] instanceof Bitmap) {
  119.             if (this._cache[image].baseTexture) {
  120.               this._cache[image].baseTexture.destroy();
  121.             }
  122.           }
  123.           delete this._cache[image];
  124.         }
  125.       };
  126.  
  127.       var _Scene_Map_create = Scene_Map.prototype.create;
  128.       Scene_Map.prototype.create = function() {
  129.         _Scene_Map_create.call(this);
  130.         if (this._transfer && (!mobile || Utils.isMobileDevice())) {
  131.           ImageManager.clear();
  132.         }
  133.       };
  134.     })();

作者: taroxd    时间: 2015-12-27 11:33
RM 所有版本都是这样的,并不会有什么问题。

正常电脑的内存是够用的。
作者: 夏末渐离    时间: 2015-12-27 13:10
我个人觉得目前主流电脑的内存已经足够适应足够大的RM游戏。
作者: 低调菌    时间: 2015-12-27 13:45
以空间换时间,以耗内存为代价换取流畅性,是软件发展的主流趋势。
作者: mitori10feet    时间: 2015-12-27 13:49
最近剛好也在查這個問題,因為一些舊型手機在執行時FPS 相當低, 這邊查到了一個preload 跟 控制記憶體使用的
插件,但怎麼都不會用,還望大神能夠教學

http://liply.net/2015/11/14/preload/
作者: 低调菌    时间: 2015-12-27 13:53
吃内存是现代软件的优化方式,如果把它“优化”掉,只能提高游戏在低配手机上的流畅性,在高配手机和电脑上会变得更卡,大内存用户的游戏体验会变差。

作者: andrewx    时间: 2015-12-27 13:54
本帖最后由 andrewx 于 2015-12-27 13:56 编辑
taroxd 发表于 2015-12-27 11:33
RM 所有版本都是这样的,并不会有什么问题。

正常电脑的内存是够用的。


但是放在手机上可能就要出问题了吧?目前移动端运行起来效率确实有点糟糕
作者: VIPArcher    时间: 2015-12-27 14:06
你看你的RM游戏一般也就几十到几百M,去掉音乐啥的。其实没多少东西的。
作者: 喵呜喵5    时间: 2015-12-27 15:10
andrewx 发表于 2015-12-27 13:54
但是放在手机上可能就要出问题了吧?目前移动端运行起来效率确实有点糟糕 ...

然而,我不觉得清空了这个图片的Cache运行效率就会立刻得到显著提升
作者: trentswd    时间: 2015-12-27 17:31
doranikofu 发表于 2015-12-27 11:17
搬运一个插件 还没研究细节
其实要能做的只能一点在事件里面调用的话应该很方便
做远景地图的话 离开一个 ...

感觉全清有点太激进了……
作者: 低调菌    时间: 2015-12-27 18:37
HTML5毕竟是新技术,目前还不是很成熟。,当初FLASH刚出的时候也是卡的要死。
作者: chaizi1992    时间: 2015-12-28 09:22
doranikofu 发表于 2015-12-27 11:17
搬运一个插件 还没研究细节
其实要能做的只能一点在事件里面调用的话应该很方便
做远景地图的话 离开一个 ...

把这个插件导入游戏里,给他加了个插件命令
切场景调用插件命令全清,游戏会崩掉
作者: garfeng    时间: 2016-5-26 22:15
本帖最后由 garfeng 于 2016-5-26 22:36 编辑

已经遇到这个问题了,而且相当严重,在玩一个别人做的复刻版伏魔记。
每走一个地图,都会load数据,对话文字啊,坐标之类的都不会占多少内存,但是图片load进来,又不释放,意味着内存整M整M的飞涨。
打一场架,技能释放的动画都像是完全重新load而不是重复使用之前的,所以打一次架内存消耗得增加几百M,这几百M在战斗结束后并不会消失,接着跑地图。
我的手机是3G的Ram,经朋友提醒,可以实时查看app占用资源情况,于是今天尝试玩一会儿就看看资源,在800M左右最后一次看,然后一场boss战,战斗期间忘记看了,打了一会儿就卡崩了。估计崩的时候,Ram占用在1G以上。

其他的,诸如微信,搜狗输入法,占用内存都在10M左右。
所以个人觉得,释放用过的资源还是必要的呀,明天好好研究下。






第一个就是游戏了。
这不像是游戏运行之初,把图片一起读出到内存里,后面直接调用(这样200M差不多了),而更像是,每次需要播放图片时,都重新申请内存存放图片,用完又不回收。
所以,除用过的内存,并不会影响游戏流畅性,因为以后要播放图片,本来就都会重新读一次。

作者: 疯子不隐士    时间: 2020-7-24 01:06
garfeng 发表于 2016-5-26 22:15
已经遇到这个问题了,而且相当严重,在玩一个别人做的复刻版伏魔记。
每走一个地图,都会load数据,对话文 ...

大佬我的游戏现在也遇到了这个问题,请问该怎么解决啊!我的qq:872007801,可以加我联系一下。或者请留下您的联系方式。
作者: q3226257    时间: 2020-7-24 11:35
garfeng 发表于 2016-5-26 22:15
已经遇到这个问题了,而且相当严重,在玩一个别人做的复刻版伏魔记。
每走一个地图,都会load数据,对话文 ...

你这种问题估计不是缓存造成的,你一场战斗要加载额外几百兆的资源吗??
缓存是加载过的不会再次加载,只有新的资源才会加载保存。

作者: q3226257    时间: 2020-7-24 11:37
这种写法存在的问题就玩着游戏一直没有退出,才存在那种越玩越卡,
但是这种情况我觉的还是不太存在,
大不了卡顿的时候,重启下游戏,
如果你是因为卡就认为是这个缓存的原因,大概率是你找错方向了!
作者: 疯子不隐士    时间: 2020-7-24 13:55
我目前就已经遇到了这个问题,因为我的游戏(必须原因)行走图设置很大,一个将近1~2M,所以跑几次地图就会出现内存飙升到1G多以上最终导致游戏崩溃,最近在寻找一种优化方案,理想的情况是游戏一边进行一边释放掉之前加载过的内存,如果大佬有相关经验可以请教一下的吗?




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