Im not sure why this works, Class referencing & memory question,

Hi,

Ive made the follwoing function to act as a quick load (test for now) as far I understand things the way ive written it shouldnt work, but it does. I’m hoping somone can explain why as I’ve obviosuly misunderstanding somthing.

public void TESTLOAD()// test quick load
    {
        int test = 1;
        if (File.Exists(Application.dataPath + "/Maps/TESTSAVE" + test + ".save"))
        {
            BinaryFormatter bf = new BinaryFormatter();
            FileStream file = File.Open(Application.dataPath + "/Maps/TESTSAVE" + test + ".save", FileMode.Open);
            SaveData saveFile = (SaveData)bf.Deserialize(file);
            file.Close();


            ZoneData zone = saveFile.world[0];// test
            int mapNumber = 0; //test
            int day = saveFile.day;

            ZoneControl.zoneControl.QuickLoad(zone, mapNumber, day);

            PlayerControl.playerControl.playerData = saveFile.playerData;// TEST will probably have to copy rather than refer
            UIControl.uiControl.UpdateInventory();
        }
        else Debug.Log("FILE NOT FOUND");
    }

Specifically

PlayerControl.playerControl.playerData = saveFile.playerData;

I would have though saveFile.PlayerData stopped existing when the fucntion ended, causing playerData to be garbage.

But it seems to work fine.

Im confused.

Cheers
Mark

Well it just works as it should :slight_smile:

Objects, data, memory becomes garbage as soon as no other object is referencing the object anymore. From a pure C# perspective there are essentially two main root anchors:

  • static variables
  • local variables of the currentl< executing method and all of it’s stacktrace.

In Unity there are some additional hidden “anchors”. Of course the Unity engine itself has internal lists of objects. Specifically the current scene and it’s gameobjects. Each gameobject has references to its components which will include your MonoBehaviour derived classes. So when you store a reference in a member variable of one of your components it is not being collected by the garbage collector since there is still a persistant reference to that object. The garbage collector can only collect objects which are not referenced by any of the “anchors” I’ve mentioned above.

Unity actually has many other hidden stored references. For example all objects derived from UnityEngine.Object are persistant since they are tracked / stored on the native C++ side and you can get back a managed reference though FindObjectsOfType. Those objects need to be destroyed through UnityEngine.Object.Destroy.

This line:

SaveData saveFile = (SaveData)bf.Deserialize(file);

Creates a new object of type SaveData and the reference is stored in the local saveFile variable.

In this line:

PlayerControl.playerControl.playerData = saveFile.playerData

you seem to store a sub object of your saveFile inside a member variable of another script. Since that other script is persistant once you store the reference in the member variable the object in playerData will stay in memory since it is still referenced even when your “TESTLOAD” methods ends.

Thats great thankyou. Makes sense now :slight_smile: