March 28th, 2007 by Kyle
Posted in: Flex, Flash Player, actionscript

I have been asked about this from various different angles and responded to it (often with ammo from others) in various different ways. I have decided to compile all info I can as a starting point to address questions hat typically come up from Flex customers regarding Flash Player Memory Management and Flash Player Garbage Collection.

CAVEAT: I am not a Player engineer and haven’t looked at the Flash Player code, but this is my understanding from several discussions with the engineers on the Flash Player and Flex Teams. (Some of this info is taken directly from emails, forum postings and conversations I have had with Alex Harui, Matt Chotin and Gordon Smith.)

Also, Grant Skinner goes into far more detail on his blog about Flash Player Memory management and Garbage Collection.
If you want to know more than the high level that I am going to address here you should check out his blog entries:

http://www.gskinner.com/blog/archives/2006/09/resource_manage.html
http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html
http://www.gskinner.com/blog/archives/2006/09/garbage_collect.html

The underlying Flash player is essentially a garbage collection memory model. That means that if nobody has a reference to an object, it will be collected and thrown out eventually. Thus, you never have to delete anything, just make sure all of your references to it are broken by removing objects from the displaylist, removing event listeners or using weak listeners where appropriate.

The Flash Player runs within the browser’s memory space and Firefox or IE give memory to the player. The browsers are then responsible for the memory and will release it to the heap.

Here is a general description of what is generally going onwith memory management as an app runs:

The Flash Player grabs OS memory in large chunks, divides them up into smaller chunks and allocates those small chunks to the application. As the number of small chunks dwindles, the player runs a GC pass to see
if any of those small chunks can be freed before we go to the OS for another big chunk. If the application is idle and nothing is accessing memory, nothing is going to force a GC pass so nothing will ever get freed.

So lets say the Flash Player allocated 40 megs. If the app happened to get to 33 megs there may be no need for the Player to GC. And it could be that in reality the Player could get away with only 20 megs, but it will take that whole 40 b/c the OS is letting it. Still not technically a memory leak, even if you think the Windows Task Manager should show less.

The MemoryMonitor tries to force a GC pass (see the hack comment in the code). It is unclear as to whether the hack works perfectly.

GC is opportunistic. This means it does not run all of the time. It tends to be triggered by allocating memory instead of freeing it, so watching an idle app will almost never result in GC. Because of the fact that GC is more or less “opportunistic”, there is no current way to manually test for memory leaks. I think there are situations where lots of activity forces several large chunks to be acquired from the OS and then, when most of that stuff is freed, each of the large chunks has a few small chunks still in use and so the OS chunks are not released back to the OS because there isn’t enough activity to cause a GC pass. Therefore, the only way we “prove” there is a memory leak issue is to use MemoryMonitor’s callback to repeat a sequence over and over again.

Now, lets look at an example.

Read the rest of this post»


No Comments »

March 22nd, 2007 by Kyle
Posted in: Flex, actionscript

You technically cannot do this, since callLater() actually takes a function as an argument and a setter is an accessor.

However, rules where meant to be broken (or at least worked around).

You can do it by creating a function inline which sets the property within your callLater invocation.

Here is a simple class with a method and a setter:

package
{
    import mx.controls.Alert;
    public class MyClass
    {
        public function set stuff(value:String):void{
            Alert.show("setter for stuff: " + value);
        }      
       
        public function junk(value:String):void{
            Alert.show("function junk: " + value);
        }
    }
}
 

Here is a simple app demonstrating the workaround:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">
   
    <mx:Script>
        <![CDATA[
            public var foo:MyClass;
       
            public function init():void{
                foo=new MyClass();
            }
        ]]>
    </mx:Script>

<!–
    The following will not compile with this error:

Error 1119: Access of possibly undefined property stuff through a reference with static type MyClass.

    <mx:Button label="call setter within callLater"
        click="callLater(foo.stuff,[’bunch of stuff’])"/>      
–> 
    <mx:Button label="call function within callLater"
        click="callLater(foo.junk,[’bunch of junk’])"/> 
    <mx:Button label="call setter within callLater"
        click="callLater(function():void{foo.stuff=’bunch of stuff’})"/>       
</mx:Application>
 

A complete Flex Builder 2.0.1 Project Archive (.zip) of this sample can be found here.


No Comments »

March 20th, 2007 by Kyle
Posted in: Flex, Flash Player

I have been asked this a few time by customers and figured this was worthy of a quick post:

The release and debug player cannot co-exist on a machine.
(You can’t have release and debug activeX or release and debug plugin installed at the same time, but you can have release activeX and debug plugin)

A player (plugin/activeX control) with the same version#, regardless of debug or release type cannot upgrade an installed player with the same version#. You must first uninstall the player then install the other version of the same player# to switch between release and debug player of the same version#.

The debug player is not available to the general public; it is only available within purchase products (like Flash Authoring, Flex Builder, FDS).

A debug swf will run in either player, but only produce trace and throw RTEs in the debug player.

You can determine what version of the player you are running from within a Flex app using the following code:

<mx:Label text="{Capabilities.playerType} {Capabilities.version} {(Capabilities.isDebugger)? ‘debugger’ : ‘release’}"/>
 

No Comments »

March 16th, 2007 by Kyle
Posted in: Flex, Flex Charting, mxml

I wrote a small sample for a customer to demonstrate how to write a Charting Datatip Renderer and Axis Label Renderer that displayed HTML links that when clicked on open up other web pages.

I based my renderers on the TextArea component, since that component has a link event that gets fired off if the TextArea htmlText contains an anchor tag that has an href that contains “event:”.

Here is the DataTip Renderer, MyDataTipRenderer.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:TextArea xmlns:mx="http://www.adobe.com/2006/mxml" borderStyle="outset"
    editable="false" selectable="true" link="linkHandler(event)" fontSize="16" >
   
    <mx:Script>
        <![CDATA[
       
        import flash.events.TextEvent;

        public function linkHandler(event:TextEvent):void {
            // Open the link in a new window.
            navigateToURL(new URLRequest(event.text), ‘_blank’)
        }

        override public function set data(value:Object):void
        {
            super.data=value;
            htmlText="<a href=’event:http://www.google.com/search?hl=en&q=" + data.chartItem.yValue + "+" + data.chartItem.xValue + "&btnG=Google+Search’>" + data.chartItem.yValue + ":" + data.chartItem.xValue + "</a>";
        }
        ]]>
    </mx:Script>
</mx:TextArea>
 

Read the rest of this post»


No Comments »

March 16th, 2007 by Kyle
Posted in: Flex, actionscript, mxml

I wrote a simple little extension to ComboBox to allow the dropdown to expand to the width of the widest entry and the ComboBox input to expand/contract to the width of the selected item. This is based on the simple ComboBox sample from the docs found here.

Here is the source code for the component:

<?xml version="1.0" encoding="utf-8"?>
<mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()" change="onChange(event);">
    <mx:Script>
        <![CDATA[
       
            import mx.controls.ComboBase;
            import mx.core.EdgeMetrics;
       
            private function init():void{
                this.dropdownWidth=calculatePreferredSizeFromData(this.dataProvider.length).width;
            }
           
            private function onChange(e:Event):void{
                var txt:String = itemToLabel(selectedItem);
                if(measureText(txt).width > 0){
                
                    var buttonWidth:Number = getStyle("arrowButtonWidth");

                    // Text fields have 4 pixels of white space added to each side
                    // by the player, so fudge this amount.
                    // If we don’t have any data, measure a single space char for defaults

                    var bm:EdgeMetrics = borderMetrics;

                    var textWidth:Number = measureText(txt).width + bm.left + bm.right + 8;
                    this.width = textWidth + buttonWidth;
                }   
                else {
                    this.width=DEFAULT_MEASURED_MIN_WIDTH
                }
            }
        ]]>
    </mx:Script>
</mx:ComboBox>
 

Read the rest of this post»


No Comments »

March 9th, 2007 by Kyle
Posted in: Flex, actionscript, mxml

I recently had a customer who was trying to debug his Flex components. Under certain circumstances the updateDisplayList() method of his component was getting called and it wasn’t obvious why.
In writing and debugging Flex components sometimes it would be useful to be able to see who called what method to figure out what is going on. Profilers are good for this, but unfortunately there is no Flex 2.0 (or 2.0.1) profiler. In speaking with Flex Engineer, Alex Harui (see his blog here), he suggested the strategy below:

  • Subclass the component you are interested in (or if you are writing your own components just add the following to your component).
  • Override the invalidateDislayList() method (or whatever method you are interested in).
  • Create a new error object.
  • Dump out the error objects getStackTrace() method.

This should get you the hierarchy of calls that caused the invalidateDisplayList call.
(And it is the calling of invalidateDisplayList that will flag the updateDisplayList() to be called.)

Read the rest of this post»


2 Comments »


Professional Medicines, Online Pharmacy buy clomid buy viagra buy cialis buy tramadol buy soma buy levitra buy propecia buy ultram buy acomplia buy phentermine buy xenical buy kamagra Online Pharmacy Products
cialis consultation delivery discount health man cialis cialis forum cialis side eefects low cost generic generic cialis pills effectiveness viagra levitra cialis cheapest generic viagra and cialis pills cat 6 cialis bargain levitra levitra cialis dysfunction erectile levitra viagra 2003 cyalis levitra market sales viagra clarinex stimula levitra aldara pay pal order diflucan viagra, cialis, levitra, diflucan, clomid buy generic soma dream levitra online order pharmaceutical zithromax price soma prescriber information soma aura soma color therapy essences soma carisoprodol 350mg soma restaurant scottsdale buy pfizer viagra viagra buying online story viagra viagra before and after viagra substituts modo de empleo viagra viagra suppositories side effects viagra testemonials viagra videos