第一次问这里。我的经验只是"高级初学者"。问题是关于由于 Unity 中的对象实例化而导致的内存中的变量存储。
需要一点来解释设置:
在我的场景中,我实例化了整个starsystem
。该脚本最多可以创建 8 颗行星,每颗行星最多有 3 颗卫星和 4 个锚点(空gameObjects
(。我不更改场景,我只销毁starsystem
并实例化新场景,所以我需要确保所有旧引用都从内存中消失。我想确保我不会在这里通过用永远不会删除的gameObjects
填充内存来产生内存泄漏。
下面是我的脚本中实例化卫星的部分,可以在单个系统实例化中多次调用。月亮gameObject
将在实例化后"返回"给调用方,并添加到调用方中创建的另一个变量中,这是它的官方变量,称为planetXMoonY
,每个系统只能存在一次,并将在新系统实例化之前nulled
。
在版本 1 中,我在方法中创建临时变量,在版本 2 中,我在外部创建它们,并在实例化之前首先重置它们。
如何在内存中处理?我看到正确的是,一段时间后在版本 1 中,内存中可能在技术上newMoon
GameObjects
数十个或更多?同名,但当然有单独的实例ID
,我会填满内存。
当对象planetXMoonY
被销毁时会发生什么?当我理解正确时,不再与newMoon
变量连接,但是planetXMoonY
引用将被GC()
及时删除。但是,如果没有直接调用将其设置为null
,newMoon
变量是否会从内存中删除?
所以我想也许版本 2 是一个改进。首先将其重置为 null 以确保garbageCollector
及时删除所有newMoons
是否有帮助,因为在返回gameObject
后不需要它们,这里只是为了实例化目的。但是我仍然以这种方式创建数十个,还是仅创建一个?
我希望这个问题足够清楚。我似乎在这里错过了对内存使用的一些基本理解。我想我在这里缺少一个关于如何正确安全地创建变量的非常重要的知识,我想确保我未来的工作流程得到改进。提前感谢您的帮助。
贝/莱 星人
版本1:
private GameObject InstantiateMoon(GameObject moon, GameObject planetSphere, float moonSphereRadius, float moonOrbit, float MoonOrbit_Y)
{
GameObject newMoon = Instantiate(moon, planetSphere.transform.position, Quaternion.identity, spheresContainer.transform) as GameObject;
GameObject newMoonSphere = newMoon.transform.Find("MoonSphere").gameObject;
newMoonSphere.transform.localScale = new Vector3(moonSphereRadius, moonSphereRadius, moonSphereRadius);
newMoonSphere.transform.localPosition = new Vector3(0,0,moonOrbit);
newMoon.transform.localRotation = Quaternion.AngleAxis(MoonOrbit_Y, Vector3.up);
DrawCircle orbitLine = newMoon.transform.Find("OrbitLine").gameObject.GetComponent<DrawCircle>();
orbitLine.InitializeLine(moonOrbit);
newMoon.transform.SetParent(planetSphere.transform);
return newMoon;
}
<小时 />版本2
private GameObject newMoon;
private GameObject newMoonSphere;
private DrawCircle orbitLine;
private GameObject InstantiateMoon2(GameObject moon, GameObject planetSphere, float moonSphereRadius, float moonOrbit, float MoonOrbit_Y)
{
newMoon = null;
newMoonSphere = null;
orbitLine = null;
newMoon = Instantiate(moon, planetSphere.transform.position, Quaternion.identity, spheresContainer.transform) as GameObject;
newMoonSphere = newMoon.transform.Find("MoonSphere").gameObject;
newMoonSphere.transform.localScale = new Vector3(moonSphereRadius, moonSphereRadius, moonSphereRadius);
newMoonSphere.transform.localPosition = new Vector3(0,0,moonOrbit);
newMoon.transform.localRotation = Quaternion.AngleAxis(MoonOrbit_Y, Vector3.up);
orbitLine = newMoon.transform.Find("OrbitLine").gameObject.GetComponent<DrawCircle>();
orbitLine.InitializeLine(moonOrbit);
newMoon.transform.SetParent(planetSphere.transform);
return newMoon;
}
长话短说,第二个函数并不是一个改进。
执行此操作时:
newMoon = Instantiate(moon, planetSphere.transform.position, Quaternion.identity, spheresContainer.transform) as GameObject;
前一个值从private newMoon
成员中分离出来,如果它不与代码中的另一个变量关联,则垃圾回收器将选取该值。
GC 将在不使用记录器时选取对象。如果对象未分配给变量,则将其视为未使用。
第一个函数中的变量本身在函数结束时不再存在。它返回对对象的引用,如果未在任何地方分配,则对象本身也将由 GC 拾取以进行处置。
这主要取决于您在函数之外做什么,而不是内部发生的事情。
如果您的内存使用是一个问题,请检查众所周知的 GoF 蝇量级模式 https://en.m.wikipedia.org/wiki/Flyweight_pattern 在您的情况下,我认为这会有所帮助。