C# 不要将它们从内存中实际移除,而是将它们隐藏起来。50+MB的Texture2D资源有点奇怪,因为您还需要加载120+MB的网格。我假设这是一个3D游戏,但是有一个2D用户界面?如果是这样,那么在Texture2D资产上花费50MB是相当大的
“对象”就是你所认为的——它们是对象。实例化类或包含附加组件的游戏对象。因此,如果你制作了一个玩家游戏对象,并附加了一个“玩家状态”对象,该对象包含两个变量,如健康、速度、耐力等,那么该对象将计为2个对象C# 不要将它们从内存中实际移除,而是将它们隐藏起来。50+MB的Texture2D资源有点奇怪,因为您还需要加载120+MB的网格。我假设这是一个3D游戏,但是有一个2D用户界面?如果是这样,那么在Texture2D资产上花费50MB是相当大的,c#,ios,unity3d,memory,texture2d,C#,Ios,Unity3d,Memory,Texture2d,“对象”就是你所认为的——它们是对象。实例化类或包含附加组件的游戏对象。因此,如果你制作了一个玩家游戏对象,并附加了一个“玩家状态”对象,该对象包含两个变量,如健康、速度、耐力等,那么该对象将计为2个对象 80MB对于对象来说并不太令人担忧。对于一款以iOS为目标的游戏来说,你的纹理2D和网格使用会让我觉得相当高。请确保您使用的是对移动设备友好的模型和分辨率不太高的纹理。我在iOS中遇到过类似的音频文件问题,我不知道这是否是您的情况 我在内存中加载了20mb+的大音频文件来处理它们,然后释放内存
80MB对于对象来说并不太令人担忧。对于一款以iOS为目标的游戏来说,你的纹理2D和网格使用会让我觉得相当高。请确保您使用的是对移动设备友好的模型和分辨率不太高的纹理。我在iOS中遇到过类似的音频文件问题,我不知道这是否是您的情况 我在内存中加载了20mb+的大音频文件来处理它们,然后释放内存,问题是xcode分析器中的内存一直在增加。这是由内存碎片引起的,您可以在此处阅读更多信息:
我的解决方案是将文件分小块加载,并重用我的数组,而不是创建和销毁新的数组。在运行探查器的情况下运行应用程序了吗?这将让你看到到底是什么在使用这么多的内存。在使用你的应用程序一段时间后,你能上传详细内存分析器的屏幕截图吗?你必须销毁每一个未使用的纹理,否则它将保留在内存中。@JuanBayonaBeriso用截图编辑了我的问题。@Eoghan探查器并没有告诉我太多。特别是如果你考虑到它说我使用的内存比Xcode显示的要少100 MB。我也不确定83.5MB的“对象”是什么意思。谢谢你的回答!重新考虑我的网格和纹理让我恢复了60 MB的速度。但记忆的积累仍然很大。我发现如下:当调用
sendmailtask
时,探查器中的内存使用量增加了150MB,其中54MB是对象,96MB是纹理2D(三幅图像,每幅32MB)“未保存”。但是,当调用SendImage1
并销毁所有内容时,探查器仅显示整个应用程序从295 MB增加到302 MB的7 MB。另一边的Xcode从247MB增加到372MB,这是新的基线。是的,那可能就是它了?你能重复使用你的纹理记忆而不是创建新的吗?我不知道你是如何加载它们的,因为你正在使用斯坦资产插件。谢谢你的回答!你能看看我对下面答案的评论吗?看起来碎片也可能是我的问题,因为我正在加载这三个32MB的Texture2D。你怎么认为?
public class Picture : MonoBehaviour {
private int ssCount = 0;
private Sprite cachedImage1sprite;
private Sprite cachedImage2sprite;
private Sprite cachedImage3sprite;
private Texture2D cachedImage1;
private Texture2D cachedImage2;
private Texture2D cachedImage3;
private Texture2D JPGtex1;
private Texture2D JPGtex2;
private Texture2D JPGtex3;
private Texture2D tex;
void Awake () {
}
// Use this for initialization
void Start () {
JPGtex1 = new Texture2D (2, 2, TextureFormat.RGB24, false );
JPGtex2 = new Texture2D (2, 2, TextureFormat.RGB24, false );
JPGtex3 = new Texture2D (2, 2, TextureFormat.RGB24, false );
// Create a texture the size of the screen, RGB24 format
int width = Screen.width;
int height = Screen.height;
tex = new Texture2D( width, height, TextureFormat.RGB24, false );
}
// Update is called once per frame
void Update () {
if (ssCount == 0) {
SendEmail.interactable = false;
TakePhoto.interactable = true;
} else if (ssCount == 1) {
SendEmail.interactable = true;
} else if (ssCount == 3) {
TakePhoto.interactable = false;
}
//Debug.Log (ssCount);
}
void SendEmailTask(){
if (ssCount == 3) {
cachedImage1 = SA.IOSNative.Storage.AppCache.GetTexture ("IMAGE_1");
cachedImage2 = SA.IOSNative.Storage.AppCache.GetTexture ("IMAGE_2");
cachedImage3 = SA.IOSNative.Storage.AppCache.GetTexture ("IMAGE_3");
ImagePicker.SetActive (true);
//Image1
Rect rec1 = new Rect(0, 0, cachedImage1.width, cachedImage1.height);
cachedImage1sprite = Sprite.Create(cachedImage1, rec1, new Vector2(0,0),1);
Image1.image.sprite = cachedImage1sprite;
//Image2
Rect rec2 = new Rect(0, 0, cachedImage2.width, cachedImage2.height);
cachedImage2sprite = Sprite.Create(cachedImage2, rec2, new Vector2(0,0),1);
Image2.image.sprite = cachedImage2sprite;
//Image3
Rect rec3 = new Rect(0, 0, cachedImage3.width, cachedImage3.height);
cachedImage3sprite = Sprite.Create(cachedImage3, rec3, new Vector2(0,0),1);
Image3.image.sprite = cachedImage3sprite;
SA.IOSNative.Storage.AppCache.Remove ("IMAGE_1");
SA.IOSNative.Storage.AppCache.Remove ("IMAGE_2");
SA.IOSNative.Storage.AppCache.Remove ("IMAGE_3");
}
}
IEnumerator TakeScreenshot() {
// Wait till the last possible moment before screen rendering to hide the UI
yield return null;
GameObject.Find("Buttons").GetComponent<Canvas>().enabled = false;
FlashImage();
// Wait for screen rendering to complete
yield return new WaitForEndOfFrame();
// Create a texture the size of the screen, RGB24 format
int width = Screen.width;
int height = Screen.height;
// Read screen contents into the texture
tex.ReadPixels( new Rect(0, 0, width, height), 0, 0 );
tex.Apply();
//byte[] screenshot = tex.EncodeToPNG();
print("Size is " + tex.width + " by " + tex.height);
if (ssCount == 0) {
SA.IOSNative.Storage.AppCache.Save ("IMAGE_1", tex);
ssCount++;
} else if (ssCount == 1) {
SA.IOSNative.Storage.AppCache.Save ("IMAGE_2", tex);
ssCount++;
} else if (ssCount == 2) {
SA.IOSNative.Storage.AppCache.Save ("IMAGE_3", tex);
ssCount++;
}
IOSCamera.Instance.SaveTextureToCameraRoll(tex); //Save to Cameraroll
// Show UI after we're done
GameObject.Find("Buttons").GetComponent<Canvas>().enabled = true;
}
public void SendImage1() {
byte[] screenshot1;
screenshot1 = cachedImage1.EncodeToJPG ();
if (Facebook == false) {
JPGtex1.LoadImage (screenshot1);
TextureScale.Bilinear (JPGtex1, 1200, 900);
IOSSocialManager.Instance.SendMail (SubjectText, EmailText, "", JPGtex1);
} else {
StartCoroutine(UploadToPage(screenshot1));
}
backToGame ();
}
public void backToGame() {
Destroy (cachedImage1sprite);
Destroy (cachedImage2sprite);
Destroy (cachedImage3sprite);
SA.IOSNative.Storage.AppCache.Remove ("IMAGE_1");
SA.IOSNative.Storage.AppCache.Remove ("IMAGE_2");
SA.IOSNative.Storage.AppCache.Remove ("IMAGE_3");
Destroy(cachedImage1);
Destroy(cachedImage2);
Destroy(cachedImage3);
cachedImage1 = null;
cachedImage2 = null;
cachedImage3 = null;
Image3Obj.SetActive (true);
ImagePicker.SetActive (false);
}
}