Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by derek9975 · Jan 07, 2015 at 07:41 PM · ioswwwmemory leak

Creating a MemoryStream from WWW.bytes leaks memory

I'm currently using Unity 4.5.5f1 and creating an iOS application using XCode 6.1.1

I've externalized many assets n 4 different zip files. I download them using the WWW class. I unzip and save the assets to the disk and all is cool with that. However, testers came back with the app crashing on lower memory devices (iPad Mini, iPad2) on first play through after the downloading completed. Additional note: This coroutine is contained in a monobehaviour class that is added as a component prior to use and destroyed after it is done being used.

I have broken down my code to the problem, but I don't know the solution. The problem arises when I create a MemoryStream using the bytes from the WWW class. I have a simple coroutine that downloads the zip file, creates the memory stream, unzips/writes/saves files, and then finishes. I have the coroutine down to 2 elements now (download the zip, create the memory stream).

 public IEnumerator DownloadAndProcessZip(string path, string pathToSaveFilesTo)
     {
         percentComplete = 0.0f;
 
         using(WWW www = new WWW(path))
         {
             while(!www.isDone)
             {
                 percentComplete = www.progress * 0.5f;
                 yield return 0;
             }
 
             //create the memory stream with the www.bytes
             //using(MemoryStream zipFileStream = new MemoryStream(www.bytes))
             {
                 //after it is downloaded
                 //I'm doing nothing for now
             }
 
             yield return 0;
         }
         System.GC.Collect();
         System.GC.WaitForPendingFinalizers();
         percentComplete = 1.0f;
     }

As you can see, I have the MemoryStream creation commented out. This results in the following memory usage: alt text

As you can see the 4 spikes in memory are the downloading of the zips and then the memory gets dumped and all is well. The last spike is immediately followed by background level loading so the memory doesn't get back down to the 30mb I started with prior to downloading.

Once I un-comment the MemoryStream creation:

  public IEnumerator DownloadAndProcessZip(string path, string pathToSaveFilesTo)
         {
             percentComplete = 0.0f;
     
             using(WWW www = new WWW(path))
             {
                 while(!www.isDone)
                 {
                     percentComplete = www.progress * 0.5f;
                     yield return 0;
                 }
     
                 //create the memory stream with the www.bytes
                 using(MemoryStream zipFileStream = new MemoryStream(www.bytes))
                 {
                     //after it is downloaded
                     //I'm doing nothing for now
                 }
     
                 yield return 0;
             }
             System.GC.Collect();
             System.GC.WaitForPendingFinalizers();
             percentComplete = 1.0f;
         }

I get this memory usage: alt text

The drop furthest to the right is when the last file has finished downloading. As you can see from the code I am using using and my IDisposable objects should be cleaned up/disposed of properly once they fall out of scope. This is a huge problem. I'm starting in the hole by roughly 120-150mb stuck in memory and when you only get about 250ish on the low memory devices to play with before you have problems, that is a huge issue.

I saw that the WWW class for iOS had a memory leak prior to 4.5 and I found the code and indeed the _data is being released once and I found the retain for the NSMutableData so that should be good. Is it possible it is getting retained elsewhere in Obj-C that it needs to be released with? I'm running out of ideas here and this is a major issue.

Thank you in advance for any help.

Edit 1 and Possible Work Around So I have a thought as to why this is occurring. By accessing the content (in this case bytes) of the WWW, they have to be passed from the Obj-C native side to the scripting side. How this occurs, I have no clue as the code is hidden from me. If it is like writing an iOS plug in that returns a char , you have to allocate a new char and pass it over. I have a feeling that this copy is being held onto in memory, or the reference count of the NSMutableData array is being retained but never subsequently released and when the clean up occurs, it releases and nils the _data, effectively losing the reference and then that memory is leaked.

I found a downloading alternative here: Top Answer I fiddled with the code some and now I can download the files directly to disk and the memory never spikes. I can't attach any more pictures unfortunately, but the memory sits @ roughly 32mbs for the entire download process.

I'm not sure if this is the best or most right solution to this problem, but it does work. I would suspect a properly working WWW class in Unity would be the preferred way of handling this. So if anyone has any other solutions, I'm all ears. Thanks again

screen shot 2015-01-07 at 11.31.34 am.png (19.1 kB)
screen shot 2015-01-07 at 11.19.39 am.png (19.4 kB)
Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Graham-Dunnett ♦♦ · Jan 07, 2015 at 07:41 PM -1
Share

$$anonymous$$aybe the best answered question I have ever seen on Answers. Gave you a karma boost for it.

avatar image tswalk · Jun 13, 2016 at 07:42 PM 0
Share

over a year later and this is still a problem...

avatar image DeveshPandey · Jan 14, 2018 at 08:48 AM 0
Share

Here is the great plugin to download any small/big files without memory leak.

https://www.assetstore.unity3d.com/#!/content/92128?aid=1101l34jr

For more details, visit this blog

http://unitydevelopers.blogspot.in/p/blog-page_13.html

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by DanSuperGP · Jan 07, 2015 at 09:24 PM

Something that's sticking out to me is that you're not calling zipFileStream.Close() before you dispose of everything.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image derek9975 · Jan 07, 2015 at 10:01 PM 1
Share

Isn't that what the using statement does? Once that object falls out of scope the Dispose function is called (I think, C#'s finer points escape me at times)

avatar image DanSuperGP · Jan 07, 2015 at 10:13 PM 0
Share

Yes, you are correct, sorry...

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

crash memory allocation with Resources.Load() 2 Answers

www 404 error only on iOS 1 Answer

WWW.h crash in store build 5 Answers

Assetbundle memory leaks 0 Answers

Download then open image on IOS 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges