I believe that this question was discussed many times, but still.
Consider an example:
We have some kind of singleton class which exists all the time.
It has public GameObject MyGameObject;
We load scene1. And set MyGameObject = GameObject.Find(“Whatever”);
Then we load scene2.
Now Debug.Log(MyGameObject == null) will say “true”. I suppose somekind of wrapper still exists, which knows that this GameObject doesn’t exists anymore. We can’t even find it using FindObjectsOfTypeAll (and we can’t find source asset). So Unity knows that object was destroyed, but it still keeps texture alive! (after calling UnloadUnusedAssets of course).
So until we excatly set MyGameObject = null; we can’t get rid of texture it uses in our memory.
This is very simple example, in reality everything can be very unobvious. We can reference another class, which can refenrece gameobject which was destroyed and it’s component can has delegate in which closure still exists local variable of another gameobject and etc…
I understand that this is our problem and we should keep eyes on our code, but I’m really interested in reasonable explanation why is it so?