Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
0
Question by Zinggy · Feb 11, 2016 at 02:00 PM · androidwwwmemory leak

WWW Android Memory Leak?

Hello,

I am developing a Gear VR application that must download a number of large video files. I'm finding that after downloading roughly six or more ~100 MB files, the app behaves as if it is running out of memory-- failing to load assets or crashing on scene loads. If the app is rebooted, it does not download the files again (as it finds them in persistentDataPath) and behaves as expected. I have restructured the code several times, either utilizing using() blocks, manually calling www.Dispose(), and aggressively calling System.GC.Collect(), but none of that had any effect on the behaviour.

It's worth noting that this problem only occurs on the Note 4. S6s are able to proceed without issue, I'm presuming because they have enough spare memory to operate correctly even with the leak. It's also possible that WWW is not at fault and something else (maybe System.IO.Filestream) is the root of the problem.

Also of note: the same problem was observed in a previous version of the app that used WWW to transfer the files out of StreamingAssets via a jar:// URI, rather than fetching the files from an external server.

I'm using Unity 5.2.2.p4. I've found mentions of a WWW memory leak on iOS, but that was presumably patched several versions ago, and is an entirely different platform in any case.

Code follows, trimmed for clarity:

     private void Start()
     {
          StartCoroutine(AllDownloads());
     }

     private IEnumerator AllDownloads()
     {
         foreach (VideoInfo video in mVideos)
         {
             yield return StartCoroutine(Download(video));
         }
     }
 
     private IEnumerator Download(VideoInfo video)
     {
         string writePath = Application.persistentDataPath + "/" + video.Name;
 
         WWW www = new WWW(Host + video.Name);
         while (!www.isDone)
         {
             yield return new WaitForSeconds(0.1f);
         }
 
         if (!string.IsNullOrEmpty(www.error))
         {
                 //Error Handling Code -- snipped - Loads a different scene, destroying this object.
                 yield break;
         }
 
         System.IO.FileStream file = System.IO.File.Create(writePath);
         int written = 0;
         byte[] bytes = www.bytes;
         while (written < www.bytesDownloaded)
         {
             try
             {
                 file.Write(bytes, written, Mathf.Min(CHUNK_SIZE, www.bytesDownloaded - written));
             }
             catch(Exception)
             {
                 //Error Handling Code -- snipped - Loads a different scene, destroying this object.
                 yield break;
             }
             
             written += CHUNK_SIZE;
             yield return null;
         }
         www.Dispose();
         www = null;
         file.Close();
         file.Dispose();
         file = null;
         bytes = null;
     }
 }




Comment
Add comment · Show 2
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 Teravisor · Feb 11, 2016 at 09:28 PM 1
Share

Have you tried attaching profiler? What does memory profiling say?

avatar image DeveshPandey · Jul 18, 2017 at 07:30 PM 0
Share

Download big files in Android & iOS without memory leaks

http://u3d.as/RDf

It also works on PC and $$anonymous$$AC

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Zinggy · Feb 14, 2016 at 02:05 AM

It seems I was too quick to place the blame with WWW. This problem was actually a quirk of the Garbage Collector.

Memory profiling revealed that, as I expected, each file download was accompanied by a 100MB jump in Mono's used and reserved memory that was never released, causing significant performance issues and scene/texture load failures once it exceeded about 500MB.

The interesting part is that the 100MB jumps didn't happen during the download or during the file write operation, but in the line

     byte[] bytes = www.bytes;

Whatever WWW uses for internal storage is invisible to the profiler, but the bytes accessor presumably converts it into a byte array in managed (Mono) memory. That massive byte array is the real problem.

Turns out I'm bumping into something called the Large Object Heap (or Large Object Space in Mono terms). This is a memory space where particularly large allocations are placed that isn't treated normally by the garbage collector, and in some fringe cases like mine, it can actually be extremely inefficient.

There's not really a "solution" that doesn't involve dodging the WWW class (i.e., the ideal case would be to be able to write the bytes to file in small chunks as they're downloaded, but WWW only gives us access to a monolithic byte array once the whole download is complete). However, by adjusting the end of the file write loop like so

     bytes = null;
     System.GC.Collect();

I can get the Garbage Collector to behave well enough that the wasted memory is kept below 350 MB or so, which lets the rest of the app function normally.

Comment
Add comment · 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

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Handheld.PlayFullScreenMovie() works on Android but not iOS? 2 Answers

WWW and SSL on Android 1 Answer

WWW.audioClip not playing on android build 1 Answer

Troubles with network in development build with Android 0 Answers

WWW with HTTPS on Android not working 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