Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Holy spit! Don't Instantiate() the prefab running the Instantiate() code!

Discussion in 'General Discussion' started by Deleted User, Apr 27, 2017.

  1. Deleted User

    Deleted User

    Guest

    Yeah. I just tried to spawn 250 asteroids at scene start and Unity froze. I tried that three times before I realized my prefab had the spawning script attached to it. So it was filling up memory with x^x prefabs!
     
  2. Farelle

    Farelle

    Joined:
    Feb 20, 2015
    Posts:
    504
    ouch lol
     
  3. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,614
    I think it'd be doing more than that...
     
  4. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    Yeah you'd be getting an infinite recursion loop. Meaning even one Asteroid would probably stack overflow and break your game
     
    angrypenguin likes this.
  5. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I've never seen this one stack overflow. Remember Awake and Start aren't called directly, rather they get called from the C++.

    If you use Awake it just leads to a regular infinite loop with memory filling up quickly.

    If you use Start, you can actually watch the GameObjects spawn like crazy*. After a handful of frames you'll notice the slowdown, each frame becomes longer, and the system becomes less responsive.

    Because these loops tend to fill up memory fast, it's fairly easy to use so much of the system resources that you can't even force quit Unity. (At least on Windows, Mac might have a better architecture). So you end up using the power button and hard crashing the entire system.

    Fun times.

    *For best effect add a Rigidbody, Collider and Mesh.
     
    angrypenguin and QFSW like this.
  6. gian-reto-alig

    gian-reto-alig

    Joined:
    Apr 30, 2013
    Posts:
    756
    as a general rule, never Instantiate() or Destroy() during gameplay if you can avoid it.
    Both those functions have a very high overhead, and if if call them a lot, they will kill performance.

    Instantiate at game or level start, put those instances in a pool, and reuse them, only deactivating and hiding instances if they should be destroyed. That way, your game can handle much, much more instances and faster creation / destruction rates without the CPU getting bogged down by these function calls.

    Implement a machine gun that spits out bullets as gameobjects that use Instantiate() and Destroy(), put some of those in a level and let them fire away, then make sure the machine gun instead has a fixed amount of bullets in a pool that get cycled through without destroying them, and you will see what I mean (yes I know that gameobjects probably are a really heavyweight construct for something like a bullet:))

    I know this is a little bit offtopic, but if these calls wouldn't be so heavy, you might not have run into these problems (And if you have a managed pool of instances, you will never run into these problems again unless your pool init method is bugged)
     
    Not_Sure, Socrates and Deleted User like this.
  7. Andy-Touch

    Andy-Touch

    A Moon Shaped Bool Unity Legend

    Joined:
    May 5, 2014
    Posts:
    1,479
    And there is a 50 minute Live Training Video focusing on Object Pooling! :) https://unity3d.com/learn/tutorials/topics/scripting/object-pooling
     
  8. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Well no. It just would have taken two seconds longer to kill everything. There isn't a computer yet that can deal with exponential memory growth.

    (But yes, a faster Instantiate and a modern garbage collector would be appreciated.)

    Depends. If you let your pool grow, as is often desired, you will still hit this limitation. If you don't let your pool grow you'll have a weird different bug. But it probably won't crash your computer.

    And yes, in general pools are a good idea. It just wouldn't have done much in this case.
     
    angrypenguin likes this.
  9. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    pools wouldn't have done much in this case, since you would have forced the pool to grow, or you would be limited by it and not have things spawn, and still be dealing with a for ever growing amount of calls to the spawn method. What you did here is pretty much just a fork bomb.
     
    Kiwasi likes this.
  10. Deleted User

    Deleted User

    Guest

    Yea the prefab had a RB attached to it. Pretty fun. You're absolutely correct about Unity locking up. I had to use the task man to shut it down. Also a considerable amount of patience was necessary too hahaha

    On a related note, now that I have employed OOP techniques and used the physics built in to Unity I've made more progress in the past two weeks on this project than I have in the past two years. Its always just been a large collection of separate unrelated classes which could each be 400 lines long. Originally, I didn't think it would be easy to use the physics engine with my control scheme. Turns out it was super easy! Also really should not have over-engineered it either but hey.

    I found it curious that some could develop games in a matter of weeks. Now I know why.

    Also there's no need for an object pooler in this instance because I was just spawning inside of Start() a bunch of asteroids for effect.
     
  11. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,554
    @Braineeee:

    Check this chart to see in which order monobehavior functions are called:
    https://docs.unity3d.com/Manual/ExecutionOrder.html

    Also, check limitations on serialziation mechanisms:
    https://docs.unity3d.com/Manual/script-Serialization.html


    I would say this is not a good advice and it falls into premature optimization category.

    While making initial prototype, use whatever you want. When you run into issue - IF you run into an issue - THEN implement object pooling, if you need it.
     
  12. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    My bad, I was thinking in a constructor sense when I wrote that instead of Unity's Start and OnAwake calls
     
    Kiwasi and angrypenguin like this.
  13. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,614
    You were still mostly right, though. The important bit is that the function would never have stopped being called.
     
    QFSW and Kiwasi like this.
  14. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    It's essentially the same effect. But it ends up being more of a pain because it doesn't error out as a stack overflow. If you are lucky you will get out of memory. But it's also possible for the system to just grind to a halt.
     
    QFSW likes this.
  15. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    I'm going to hop in here quick and say that unless you let Unity fill up your PCs RAM, you can kill Unity in the task manager. I've written many infinite loops and they give me plenty of time to kill Unity in the Task Manager.

    In fact, I wrote this script:
    Code (CSharp):
    1. void Start ()
    2.     {
    3.         Instantiate(this.gameObject, this.transform.position, Quaternion.identity);
    4.     }
    So as soon as I start the game, it spawns an object, then that object spawns another object and so on. However, Unity did not crash and was fully responsive, and I had plenty of time to stop playing or even go to the Task Manager. So that seems to take a very long time if you have 8GB of RAM like me, or more.
    Here's a video:
     
  16. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,614
    In this case you're spawning ~60 objects per second. In the OP's case it was 250 on the first tick, then 250^2 on the second, then 250^3rd on the next...

    So in your test case it would have taken over 15 minutes to spawn as many objects as the OP's was trying to spawn just on the second tick. That's why you had plenty of time to halt the process manually.

    That said... on a modern OS no one application should be allowed to consume enough memory to crash the whole computer. One of the jobs of an OS is to stop that kind of thing from happening. When an application needs more memory it has to request an allocation from the OS, and the OS is going to check for things like whether there's enough free for that to happen before it does it. So Unity might crash, but it theoretically shouldn't be able to crash your computer.

    Edit: And your advice is sound, you should indeed be able to kill the Editor from your Task Manager or equivalent even if it's crashed from this.
     
  17. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I'll have to try it again. I swear I have done this once before in a manner that used so much RAM as to make the task manager unusable.

    Try spawning multiple copies of the object in Start.

    Or I could just be getting old and my memory is failing me.
     
  18. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,554
    ...and then OS may remember that it has a swap file, a lot of space left on hdd, so if the stars are right, allocation sizes are small it can chew your hdd for the next 15 minutes before maybe killing the program.

    This should be fairly easy to do - just need the system to hit the swap. I think it was fairly easy to make system unresponsive using unity GI on large scenes - basically the moment OS hits the swap file hard, it'll be in state where it may take minutes for it to react to your attempt at Ctrl+Alt+Del.
     
    Last edited: Apr 28, 2017
    Kiwasi and QFSW like this.
  19. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    I've hit the swap files by accidentally adding an extra 0 to the divisions in a blender smoke sim, I can confirm it is not fun
     
    Kiwasi likes this.
  20. Not_Sure

    Not_Sure

    Joined:
    Dec 13, 2011
    Posts:
    3,546
    That gave me a chuckle.

    Thanks.
     
  21. Deleted User

    Deleted User

    Guest

    You mean your RAM is failing you.

    Heh. I detected a pun opp.