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 T_LH · Mar 09, 2020 at 06:55 AM · memoryrecursion

Achieving mutual recursion without memory issues

I've got two functions set up that I need to continuously call one another (A calls B, which in turn calls A). I understand this isn't possible without causing issues by simply directly calling each function from the other, so I've got a very simple system set up that allows each function to queue the other for execution:

 List<System.Action> toCall = new List<System.Action>();
 
 void Start() {
     toCall.Add(A);
 }
 
 void Update() {
     //  To prevent infinite looping below
     List<System.Action> tempList = new List<System.Action>();
     tempList.AddRange(toCall);
 
     for (int i = 0; i < tempList.Count; i++) {
         toCall.Remove(tempList[i]);
 
         tempList[i]();
     }
 }
 
 void A() {
     toCall.Add(B);
 }
 
 void B() {
     toCall.Add(A);
 }

Unfortunately this system seems to continually use up memory, eventually resulting in a crash, which is exactly what I'm trying to avoid. I'm not super well versed on C#'s memory management, so I may be making a silly oversight here, but any help would still be appreciated.

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

1 Reply

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

Answer by Bunny83 · Mar 09, 2020 at 03:27 PM

I don't really see a reason for an outOfMemory exceptions since all memory that is allocated would eventually be garbage collected. So the code you've shown can't be the issue. However you create a lot of garbage which could be avoided. First of all there's no need to recreate your temp list every frame. Currently you create a new list (and an internal array) every frame which will be up for collection after Update. Also AFAIK by passing A or B into the Add method you will actually create a new delegate each time. I'm not 100% sure about that but caching the method delegates would avoid such issues.

 List<System.Action> toCall = new List<System.Action>();
 List<System.Action> tempList = new List<System.Action>();
 System.Action Amethod;
 System.Action Bmethod;
 
 void Start() {
     Amethod = A;
     Bmethod = B;
     toCall.Add(Amethod);
 }
  
 void Update() {
     tempList.AddRange(toCall);
     toCall.Clear();
     for (int i = 0; i < tempList.Count; i++)
         tempList[i]();
     tempList.Clear();
 }
  
 void A() {
     toCall.Add(Bmethod);
 }
 
 void B() {
     toCall.Add(Amethod);
 }

This should only create the additional garbage and no further garbage is generated since we reuse all objects involved.


Keep in mind that if "A" for example adds "B" more than once during one iteration you can still pile up your queued executions endlessly and ultimatively you would run out of memory at some point.


Though without more information about the actual problem you want to solve with your (strange) recursion we can't really help you. Keep in mind that all recursive function can be done iteratively and vice versa. While primitive recursion can be done with just a for loop, any more complex recursion might require a stack anyways since certain information has to carry along. If your problem is not a primitive recursion problem and you want to run it forever it won't work because the deeper you go the more memory you will need regardless if you use plain recursion or your own seperate datastructures. Though implementing an algorithm iteratively with your own memory structures usually allows a much deeper recursion step than using actual recursion. The reason is for actual recursion each method call creates a new stack frame on the stack. The stack is rather small so you can't have too many nested method calls since you will eventually get a stack overflow. Moving the relevant data onto the heap you can use up your total available memory before your algorithm crashes.


Though once again without knowing more about what you're actually doing inside A and B we can't tell you what's wrong or what needs to improved or if it's possible at all.

Comment
Add comment · Show 1 · 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 T_LH · Mar 11, 2020 at 12:22 PM 0
Share

Thank you, you are correct. It turns out the memory issue was caused by something else unrelated to this.

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

127 People are following this question.

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

Related Questions

Need to use HDD instead of RAM 1 Answer

How to increase the Call Stack Size in Unity? 0 Answers

PlayerLoop called recursively! (only on IE) 1 Answer

Why does Unity crash? (and other programs in general) 1 Answer

WP8 Profiler Memory Discrepancy 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