継承したクラスのメモリライフサイクルについて

返信する
タツノコ
記事: 20
登録日時: 2020年6月15日(月) 19:07
連絡する:

継承したクラスのメモリライフサイクルについて

投稿記事 by タツノコ »

こんにちは。
Scene_Base(coreスクリプトのクラス)を継承して作ったクラスのライフサイクルについて
質問させてください。

以下のコードの場合の
「Test_Sceneクラスから作ったインスタンス」

「Test_Windowクラスから作ったインスタンス」
のメモリ確保(インスタンス化)とメモリ解放のタイミングが以下の認識で合っているかご存知でしたらご教示いただけると幸いです。

【確認したいことの具体的な例】
 以下のコードのメモリA、メモリBの確保のタイミングと
 メモリA、メモリBの確保のタイミングはコード中のコメントに書いてあるタイミングで認識が合っているかを
 確認させていただきたいと思っております。
 

コード: 全て選択

var pluginName = "test";    
var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args){
    _Game_Interpreter_pluginCommand.call(this, command, args);
    if(command === pluginName){
        switch(args[0]){
            case 'show':
                SceneManager.push(Test_Scene);<====ここでTest_Sceneのインスタンス化(メモリA確保)======
                this.wait(10);
                break;
        }
    } 
};

// Scene_Baseを継承して作るWindowクラス
function Test_Scene() {
    this.initialize.apply(this, arguments);
}

Test_Scene.prototype = Object.create(Scene_Base.prototype);
Test_Scene.prototype.constructor = Test_Scene;

Test_Scene.prototype.initialize = function() {
    Scene_Base.prototype.initialize.call(this);
};

Test_Scene.prototype.create = function(){
    Scene_Base.prototype.create.call(this);
    Scene_Base.prototype.createWindowLayer.call(this);
    this._testWindow = new Test_Window(); // <===ここでTest_Windowのインスタンス化(メモリB確保)======
    this.addWindow(this._testWindow);
};

Test_Scene.prototype.update = function() {
    Scene_Base.prototype.update.call(this);
    this.popScene(); //<===PopSceneの処理が終わったタイミングで「メモリA」と「メモリB」が解放される?======
};

 // Window_Baseを継承して作るWindowクラス
function Test_Window(){
    this.initialize.apply(this,arguments);
};

Test_Window.prototype = Object.create(Window_Base.prototype);
Test_Window.prototype.constructor = Test_Window;

Test_Window.prototype.initialize = function(){
    Window_Base.prototype.initialize.call(0,0,100,100);
};

【考察】
 ・メモリ確保について
  SceneManager.pushメソッドの中の「gotoメソッド」内で
  渡したクラスのインスタンス化を行ったのち
   「
this._scene.attachReservation();
this._scene.create();
   」
  を呼び出していたので
  おそらくここでのインスタンス化が正しいのかなと思いました。


 ・メモリ解放について
  this.popScene();内のメソッドでSceneManage.pop内のgotoメソッドで「this._scene.stop();」(this._scene:現在のシーン)のstop処理を呼び出してたので名前からしてここなのかなと思いました。

 (おそらく・・・厳密には「SceneManager.changeScene」のthis._scene = this._nextScene;でpop時に新しくインスタンスをぶっこんでるから、ここでTest_Scnenのインスタンスも、Test_Windowのインスタンスも解放されているのかなと思いました。)

ちょっと書き方がおかしなところがあると思いますが、
何卒よろしくお願いいたします。

以上です。
アバター
Plasma Dark
記事: 736
登録日時: 2020年2月08日(土) 02:29
連絡する:

Re: 継承したクラスのメモリライフサイクルについて

投稿記事 by Plasma Dark »

シーンクラスインスタンスのアロケーションは、 SceneManager.goto 内で new sceneClass(); しているので、ここですね。

解放については、到達可能でなくなったあとの(最初とは限らない)GCのタイミング、としか言えません。
popで次のシーンを入れているので、そこで参照がなくなっているなら、その後のどこかのGCで解放されるでしょう。

GCに関する概要はこちらがわかりやすいかと思います。
https://ja.javascript.info/garbage-collection

確かV8のGCはCopyingとMark-and-Sweep Compactの世代別GCを採用していたはずで、新世代GCは停止時間を抑えるためにある程度大雑把な解放の仕方をします。
特定の到達可能でないオブジェクトがどのタイミングで解放されるかは知る術がないし、気にする必要もありません。
タツノコ
記事: 20
登録日時: 2020年6月15日(月) 19:07
連絡する:

Re: 継承したクラスのメモリライフサイクルについて

投稿記事 by タツノコ »

Plasma Dark様
初めまして
タツノコと申します。
ご回答ありがとうございます!

なるほど・・・大変な勘違いしておりました。
ご丁寧にご解説な上、URLまでいただきありがとうございます!

参照が外れるタイミングは、Plasma Dark様がおっしゃっている箇所。
 参照されていたオブジェクトがルートから到達不可能なときGCによりメモリ解放される。
 だがメモリの解放のタイミングは作成者が判断することはできない。」
という形で認識しました!

URL先のページを熟読していき
Javascriptとしての知識を深めていこうと思います!

改めてありがとうございました!
返信する

“MV:質問”に戻る