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
1
Question by Marenz · Oct 13, 2013 at 01:09 PM · c#gccollectgarbage collector

GC collects variable that is still in use

I have a small class to output debug output in the GUI:

 using UnityEngine;
 using System.Collections;
 
 public class GUIConsole : MonoBehaviour 
 {
     public int numLines = 10;
     private string message;
     private Queue queue;
 
     // Use this for initialization
     void Start () 
     {
         Application.RegisterLogCallback(OnLog);
         queue = new Queue();
     }
     
     // Update is called once per frame
     void Update () 
     {
         
     }
     
 
     void OnGUI ()
     {        
         foreach ( string line in queue )
             GUILayout.Label (line);
         
         while ( queue.Count > numLines ) queue.Dequeue();
 
     }
     
     void OnLog (string message, string callStack, LogType type)
     {
         //this.message += message + "\n";
         queue.Enqueue(message);
     }
 }


When I pause execution in Unity and resume it again, I get a null reference exception. Further investigation showed that my queue variable was suddenly null. Only after I added this line in start, it stopped:

 System.GC.KeepAlive(queue);

Any idea why the GC collects my object?

[EDIT] So, some further investigation showed: It isn't just pausing & resuming. Pausing is enough. I don't need to resume. But it only happens when I pause it, modify code and tab back to unity which auto-recompiles. This auto-recompile seems to cause the problem. It then shows the error

NullReferenceException: Object reference not set to an instance of an object GUIConsole.OnGUI () at Assets/Scripts/GUIConsole.cs:26)

a few times and then of course spams it if I resume.

[EDIT] Adding the suggestions in the answer:

 using UnityEngine;
 using System;
 using System.Collections;
 
 [Serializable]
 public class GUIConsole : MonoBehaviour 
 {
     public int numLines = 10;
 
     [SerializeField]
     public Queue queue;
 
     // Use this for initialization
     void Start () 
     {
         Application.RegisterLogCallback(OnLog);
         queue = new Queue();
     }
 
     void OnGUI ()
     {        
         foreach ( string line in queue )
             GUILayout.Label (line);
         
         while ( queue.Count > numLines ) queue.Dequeue();
 
     }
     
     void OnLog (string message, string callStack, LogType type)
     {
         queue.Enqueue(message);
     }
 }


Hower this didn't help with the problem. It is still happening

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 Jamora · Oct 13, 2013 at 06:26 PM 1
Share

I wasn't able to replicate the behavior. $$anonymous$$y queue remains alive even without explicitly telling the GC to keep it alive.

I added a Debug.Log in (the empty) Update to get stuff in the Queue. Then I added this script to a GameObject, pressed play, then pause, and pause again. No null reference error.

avatar image TrickyHandz · Oct 13, 2013 at 06:30 PM 2
Share

Out of curiosity, is your Queue class set as System.Serializable. The problem may arise from the fact that Unity serializes and deserializes so often.

avatar image Marenz · Oct 13, 2013 at 06:59 PM 0
Share

TrickyHandz: I don't know how I can check that. The code you see is the whole file, I am not doing anything else with the Queue class anywhere else.

Jamora: I updated the scenario

1 Reply

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

Answer by Jamora · Oct 13, 2013 at 07:57 PM

Unity performs a serialize/deserialize cycle every time you press the Play button or recompile a script. Any reference not marked as serializable will be lost there.

The way you can (try to) keep the reference is by either making it a public field, or marking that field with the [[SerializeField]][1] attribute. Then the Unity Serializer knows to attempt to restore that after an assembly reload. Only classes that have the System.Serializable attribute can be attempted to be serialized. While System.Collections.Queue has that attribute, it is not supported by the Unity serializer.

The unity serializer can serialize

  • All classed inheriting from UnityEngine.Object, for example Gameobject, Commponent, MonoBehaviour, Texture2D, AnimationClip.. - All basic data types like int, string, float, bool. - Some built in types like Vector2, Vector3, Vector4, Quaternion, Matrix4x4, Color, Rect, Layermask.. - Arrays of a serializable type

  • List of a serializable type (new in Unity2.6)

  • Enums

Read more about Unity Serialization in the Unity Technologies Blog

You will have to implement your queue as a System.Collections.Generic.List. You will also need to rename your current Start method into OnEnable, because Start is only called once, so your log callback won't work after an assembly reload.

[1]: http://docs.unity3d.com/Documentation/ScriptReference/SerializeField.html

Comment
Add comment · Show 3 · 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 Marenz · Oct 16, 2013 at 08:28 PM 0
Share

Your answer explains pretty good what is probably happening, however, adding [Serializeable] and [SerializeField] didn't fix the problem. I added the new code to the post

avatar image Jamora · Oct 18, 2013 at 03:05 PM 0
Share

Updated my answer. Turns out Queue isn't supported by the Unity serializer.

avatar image Marenz · Oct 18, 2013 at 03:10 PM 0
Share

Thank you for the answer :)

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

17 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

Related Questions

Distribute terrain in zones 3 Answers

Multiple Cars not working 1 Answer

how to send data from client to client? 1 Answer

C# Error help ( error CS0023 The `!’ operator cannot be applied to operand of type `string’ ) ??? 1 Answer

An OS design issue: File types associated with their appropriate programs 1 Answer


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