10 Replies Latest reply on Oct 11, 2010 1:01 PM by BurtJ

    HashMap key set to null for EventDispatcher only on IE and 10.1

    BurtJ Level 1

      We thought our program was working great under Flash 10.1.  SQA gave me a Saturday headache though...  Seems that it works under Windows XP or FireFox (which is where I do my testing), but fails on Vista or Internet Explorer (and I am told Chrome, though I do not have that myself)

       

      In our actual shipping product, the Flex program runs within our internal browser, which is based on WebKit (we use Qt as our desktop application framework).  Works there in XP, but not Vista, and that is the real target of concern.

       

      I tracked the problem down by running in IE on Windows XP under FlexBuilder 3.  The following lines are where the failure occurs:

       

      ----------------------

              private var loadingObjs:HashMap = new HashMap();

       

              public function addProgressListener(object:EventDispatcher):void
              {
                  if (!loadingObjs.containsKey(object)) {
                      object.addEventListener(ProgressEvent.PROGRESS, onProgress);
                      object.addEventListener(Event.COMPLETE, onLoadComplete);
                     
                      loadingObjs[object] = 0;
                  }
              }

      -----------------------

       

      In IE, after that last statement, the loadingObjs key is set to null?  We then get a crash later in HashMap.getKey when it doesn't like finding a null key.

       

      Why would that key be null?  The object is clearly not null, or the addEventListener calls would have crashed.  When I look at 'object', I see that the 'data' and 'listData' elements are null, but the source is a valid url string.

       

      For explanation, this is part of our "progress donut."  It tracks the progress of multiple data items being downloaded.  Each 'object' is a download request, and each is tracked independently.  Each item will send a COMPLETE message so it's processing can proceed.  When all items have completed (the total number of bytes received equals the total of all bytes requested), a separate event is sent so the client program knows that it has everything it asked for.

       

      Note that this worked fine under Flash 9 and 10, and has only started to fail under 10.1.  As mentioned above, it works fine on Windows XP and on Firefox, but fails on Internet Explorer and Chrome (and under Windows Vista in our Webkit based internal browser).

        • 1. Re: HashMap key set to null for EventDispatcher only on IE and 10.1
          Flex harUI Adobe Employee

          If HashMap is a Dictionary with weak keys, then there could be GC

          differences in 10.1 that will cause the object to be GC'd or not GC'd from

          the HashMap.

          • 2. Re: HashMap key set to null for EventDispatcher only on IE and 10.1
            BurtJ Level 1

            Interesting thought, but I don't think it applies here.

             

            The 'object' (used as a key) is passed in as a parameter.  If the hashMap does not already have the key, it proceeds to add two eventListeners to the object, and then adds it to the hashMap, setting the current value to 0.  (That value will later be incremented as data is downloaded, and the progress is incremented by the downloader)

             

            The adding of the eventListeners would have crashed had the object been null.  Looking at it in the FlexBuilder 3 debugger, i can see that the 'data' and 'listData' elements are null (as expected), but that the 'source' element has the url that we expect to see there.  Thus, the object cannot be null when it is added to the map at the end of the method.

             

            FWIW, this class was written by an employee that left the company 5 years ago, a little before I joined.  It has been used by all of us as a black box that worked flawlessly all this time.  Only under 10.1 does it have trouble, and then only under IE, Chrome or Vista, still working fine in XP, Mac and Firefox.

             

            Is there something in 10.1 that changes the way complex objects are added (or supported) in hashMaps?

            • 3. Re: HashMap key set to null for EventDispatcher only on IE and 10.1
              Flex harUI Adobe Employee

              I don't know which HashMap class you are using.  I am unfamiliar with such a

              class.

               

              I don't think you understood my explanation.  If HashMap is a Dictionary

              with weak reference keys, there has to be some strong reference to the

              object in order to prevent it from being GC'd.  I'm sure it wasn't null at

              the time it was added, but it can be removed from the Dictionary at any time

              if there isn't a strong reference to it.  Attaching listeners to the object

              does not create a strong reference to the object.  Instead the object has

              strong references to the listeners.  Therefore, by your explanation, it is

              quite possible that garbage collection is running more frequently in 10.1

              and flushing objects from the HashMap sooner than you expected.

              • 4. Re: HashMap key set to null for EventDispatcher only on IE and 10.1
                BurtJ Level 1

                Well, if so, then you may have hit the nail again.  Two for two. Wow!

                 

                I don't quite understand the difference between 'weak reference' and 'strong reference' though.  I will try to Google it in the morning to see what I can learn, but if you have a quick explanation, it would definitely be appreciated.

                 

                Just got home from our first gig as The Professional Wedding Photographer.  I am bushed...!  Am currently importing 1100 images into Lightroom.  I love Adobe products!

                • 5. Re: HashMap key set to null for EventDispatcher only on IE and 10.1
                  Flex harUI Adobe Employee

                  Most references are strong:

                   

                  Foo.bar = someObject; // strong reference from Foo to someObject.

                   

                  There are two ways to create weak refs:  Dictionary and addEventListener.

                   

                  The Garbage collection walks all strong references to see if anybody is

                  still using an object.  It does not walk weak references.

                  • 6. Re: HashMap key set to null for EventDispatcher only on IE and 10.1
                    BurtJ Level 1

                    Thanks. That sounds like it makes sense.

                     

                    The last line in the method is:

                     

                         loadingObj[object] = 0;

                     

                    Here the 'loadingObj' is the hashMap, and the object is the key we are entering. It is an EventDispatcher.

                     

                    So my question is:  Does setting the value of the key'd entry to 0 create a strong reference?  That is the value that we later increment as data comes in, until it reaches 100, at which point we emit a signal and explicitely remove the key.

                     

                    If setting the value to 0 does not create a strong reference, do you have a suggestion of a simple line(s) we could add to force a strong reference key, and thus avoid any GC until we wish to explicitely remove the key?

                    • 7. Re: HashMap key set to null for EventDispatcher only on IE and 10.1
                      BurtJ Level 1

                      Back in the office, looking at the code.  I see now that HashMap is actually another legacy class of ours, probably written by that same ex-employee.  It extends flash.utils.Dictionary.

                       

                      Looking at the Adobe docs for Dictionary, I see there is an optional parameter for "(weakKeys:Boolean = false)".  Since we are not providing an argument when constructing the HashMap (and thus, the Dictionary), and the default is 'false', I believe that all keys are strong.  That in turn, leads me to believe that our keys will not be garbage collected behind our backs, and should stay there until we explicitely remove them.

                       

                      And thus the mystery remains as to why IE, Chrome and Vista show the key as null immediately after adding it (in the FlexBuilder 3 debugger) and work fine in Flash 10.0 on all platforms, and 10.1 on Firefox and Windows XP.  (Note that the actual problem is that we crash upon trying to access the keys. The debugger is simply showing me that the problem exists instantly after adding the key)

                      • 8. Re: HashMap key set to null for EventDispatcher only on IE and 10.1
                        Flex harUI Adobe Employee

                        Again, I don't know anything about your HashMap class.  If it uses a

                        Dictionary and you don't want arbitrary collection of its contents, and you

                        have a way to clean up objects that are no longer wanted, then the

                        Dictionary should be instantiated to use strong reference keys.

                         

                        The value assigned to the key does not affect the key's GC behavior unless

                        it is somehow a reference to the key itself.

                        • 9. Re: HashMap key set to null for EventDispatcher only on IE and 10.1
                          Flex harUI Adobe Employee

                          What does the getKey method look like?

                          • 10. Re: HashMap key set to null for EventDispatcher only on IE and 10.1
                            BurtJ Level 1

                            Problem is resolved... sort of...

                             

                            I eliminated the HashKey class entirely, and just reference Dictionary directly, and the problem disappears.  I don't see anything in the HashMap class code that would directly account for this, but right now we are getting thousands of user complaints daily, so "if it works, it is good enough..."

                             

                            Consulting with another programmer at work, we came to possible conclusion that our use of the Dictionary through the intermediate class may have caused an ambiguity of the actual nature of the key we were using. An Image was passed to a method asking for an EventDispatcher -- inheritence should allow this, but perhaps there was an ambuguity that IE and Firefox (and XP vs Vista) interpreted differently.

                             

                            At any rate, I can now return to the project I was supposed to be working for the past week.  Another big release of two products in three weeks. Fun time in the Big City.

                             

                            Thanks again for all your help on this!