Search the Catalog
Director in a Nutshell

Director in a Nutshell

By Bruce A. Epstein
1st Edition March 1999
1-56592-382-0, Order Number: 3820
658 pages, $24.95

Chapter 9
Memory and Performance

You must balance the sometimes conflicting requirements of disk usage, download times, memory usage, and runtime performance. Compressed media shortens the download time of a Shockwave movie, but takes longer to decompress. Bitmaps require more memory, but draw more quickly than QuickDraw shapes. There is usually a trade-off between compression and quality for digital video, audio, and bitmaps. Although efficient use of memory often improves performance, the best balance depends on the minimum playback platform and the nature of your project.

See "Determining the Appropriate Minimum Hardware Playback Platform" at http://www.macromedia.com/support/director/how/expert/playback/playback.html for details on specifying the appropriate hardware (and convincing the marketing people to go along with you).

Disk Storage and Memory Management

When you save a movie file, Director saves only the changes made since the last save. The movieFileFreeSize indicates the size of old edited or deleted cast members remaining in the movie file. File Save and Compact rewrites the current data to a temporary file, excluding any old data. Director then deletes the original file and renames the temporary file to match the original file's name. File Save As also compacts the file. Both operations require enough disk space (at least temporarily) for the compacted file in addition to the original.

Director stores cast members in internal castLibs in the order in which they are used in the Score. Director stores cast members in external castLibs in the order in which they appear in the Cast window.

Each cast member is stored only once, although it may be used multiple times (or not at all) in the Score. For internal Casts, include cast members used solely as puppetSprites in a dummy Score frame near the frame(s) to which they relate. They will be stored to disk--along with the other nearby sprite's cast members--although not loaded when the "live" frame loads. For external castLibs, use Modify Sort Usage in Score before performing File Save and Compact.

A cast member's storage order is unrelated to whether it is loaded at runtime. By default, Director does not load cast members for frames it never reaches. To load puppetSprites along with a "live" frame, place them off-Stage in a sprite channel of the live frame. Director loads cast members for off-Stage sprites, but not for invisible or muted sprite channels (see the visible of sprite property and the mute buttons in the Score window).

Memory Management

Director does not usually load all assets into memory at once. The Director movie, external castLibs, and streaming digital video and audio files may be many times larger than the available memory. Director automatically loads cast members as needed and unloads old ones to make room for new cast members.

Test your presentation on your target platform before attempting to tweak the memory loading manually. You can control loading indirectly via the preLoadMode of castLib and the purgePriority of member properties or explicitly using the preloading, idle loading, and unloading commands described later in this chapter.

Memory Allocations

Windows and the Mac OS allocate memory very differently. This affects the memory available to Projectors and is reflected in several system properties and the Memory Inspector (check the memorySize to determine how much memory is allocated to Director or a Projector). Real RAM is much faster than virtual memory (VM, in which a swap file on the hard drive is used to simulate additional RAM). Director implements its own "virtual memory" scheme, swapping data from the disk to RAM as needed. It is counterproductive for Director to load a cast member from disk only to have it swapped back out to disk by the OS (although it will be accessed faster from a hard disk cache than from a CD-ROM). Tell your users to disable RAM Doubler and similar utilities that degrade performance and confuse Director's memory management.

Multimedia is memory- and processor-intensive. Real RAM is very cheap and strongly preferred. Virtual Memory should be off if possible on the Macintosh, but on under Windows, although Windows users should also have adequate available RAM.

Macintosh memory allocation

Macintosh applications, including Director and Projectors, request a fixed block of memory when they are launched and will fail to launch unless at least the minimum requested memory is available. Check the minimum and preferred memory allocations by highlighting an application's icon and choosing the Finder's File Get Info option. These can be edited only when the application is not running.

Increase the preferred memory allocation for Director to allow you to import more cast members during authoring, and to generally improve performance. The Macintosh-only File Preferences General Use System Temporary Memory option allows Director to access additional system memory during authoring. You can use this option unless it appears to cause conflicts on your particular development machine.

A D7 Macintosh Projector requests a minimum of 4,096 KB and a maximum of 6,144 KB, by default (see Table 9-1), but some Projectors will fail to launch if the full 6,144 KB is not available. Until it is fixed in D7.0.1, set the minimum allocation to 6,144 KB manually. Adjust these defaults according to your project needs and the limits of your target playback platform.

There is rarely reason to allocate more than about 12 MB to your Macintosh Projector. Allocating 50 MB, for example, will merely consume all available RAM, leaving no headroom for the Mac OS, which will cause problems.

Macintosh Projectors built using the File Create Projector Options Use System Temporary Memory option can access additional system RAM beyond their fixed allocation. This setting is ignored when the Projector is played back on a Macintosh with Virtual Memory enabled. Avoid this option if supporting 68040 Macs. If the user has enough RAM, it is strongly recommended that VM be turned off using the Memory Control Panel on the Macintosh.

Macintosh Projector memory usage

The amount of memory your Projector will require depends on many factors, such as the monitor color depth and whether you are using digital video. By default, Fat Macintosh Projectors are allocated from 2 MB to 7.3 MB depending on the Director version, processor type, virtual memory setting, and the amount of memory available when the Projector starts. You can adjust the memory allocation manually using the Finder's Get Info command after the Projector is built. Mac OS X will adopt a similar approach to Windows, where applications do not use fixed partitions.

Table 9-1 shows how the default memory allocations for each type of Macintosh Projector vary by version and processor type. The minimum and preferred memory allocations adjust automatically when virtual memory is turned on or off. For Director 4.0.4, the minimum and preferred allocations were always 2 MB and 4 MB, respectively.

Table 9-1: Macintosh Projector Default Memory Allocation

Processor[1]

D7 Minimum/Preferred

D6.0.2 Minimum/Preferred

D5.0.1 Minimum/ Preferred

68K Mac

N/A

2,048/6,144 KB

2,048/4,096 KB

PowerMac with VM on

4,096/6,144 KB

2,048/6,1444 KB

2,048/4,096 KB

PowerMac with VM off

4,263/6,311 KB[2]

3,388/7,484 KB

2,986/5,034 KB

Use the memorySize and the freeBlock to check how much RAM the Projector successfully allocated and how much remains available.

Windows memory allocation

Windows applications (including Director and Projectors) request memory as needed from a common system pool. Windows applications do not receive fixed allocations as do Macintosh applications. The Windows-only File Preferences General Limit Memory Size option is used during authoring in D5 and D6 to simulate playback on a machine with less memory. It is not available in D7.

Unlike the Macintosh, under Windows, VM (a permanent swap file) should be enabled both during authoring and for Projectors. Some versions of Director can run without VM if more than 64 MB RAM is installed, but VM is required in most cases. D7 will fail to launch if insufficient disk swap space is available.

To configure virtual memory under Windows 95/98, double-click the System Control Panel (accessed via Settings Control Panel from the Start Menu). Choose the Performance tab, click the Virtual Memory button, and then choose Let Windows manage my virtual memory settings. See Macromedia TechNote #03516, "Windows 95 Multimedia Configuration."

Under Windows NT 3.5.1, virtual memory is configured using the Virtual Memory tab in the System Control Panel. Under Windows 3.1, virtual memory is configured using the 386 Memory Control Panel and via the CONFIG.SYS file. Under Windows 3.1, set the swap file to None (if you have enough RAM) or a Permanent swap file of about 2 MB, but don't use a Temporary swap file.

The DIRECTOR.INI file includes two options affecting disk swap space used under Windows for Projectors and during authoring:

[Memory]
ExtraMemory = kilobytes 
SwapFileMeg = megabytes 

The ExtraMemory option determines the amount of swap space (in KB) a Projector should use at runtime and defaults to 400 KB. Increase this to allocate more swap space to the Projector. The SwapFileMeg option determines the amount of swap file space (in MB) to be used during authoring only. It defaults to zero (a special setting that requests disk space equal to half of available physical RAM). Increase SwapFileMeg to perhaps 20 MB to import more cast members before running out of memory. See Appendix D, The DIRECTOR.INI and LINGO.INI Files, in Lingo in a Nutshell for additional details.

Audio buffers

The Macintosh uses a fixed audio buffer of about 400 KB. This means that it buffers less than 3 seconds of CD-quality sound (176 K/sec), but about 18 seconds of 22 kHz, 8-bit, mono sound (22 K/sec). The length of Windows audio buffers can be set via the DIRECTOR.INI file. See Macromedia TechNote #03107, which includes some sound buffer size calculations.

Media Sizes

Media elements require a lot of bandwidth (capacity) to be stored, loaded, and displayed. The throughput (ability to transfer data) of the processor, hard drive, CD-ROM, network connection, video card, sound card, memory, and Director itself determine whether playback will be instant or delayed, smooth or jerky. You must account for the latency (delay) intrinsic to some devices, especially Internet connections, and their limited bandwidth.

The following sections describe each type of asset and how to calculate its size. See http://www.zeusprod.com/nutshell/glossary.html for definitions of the words loaded, preloaded, purged or unloaded, streamed and streaming, internal castLib, internal asset, external castLib, external asset, linked, and unlinked.

TIP:  

Internal (unlinked/embedded) and external (linked) cast members are treated similarly whether they reside in internal or external castLibs. External assets are generally streamed and internal assets are generally loaded in their entirety into memory when they are needed.

There are four different aspects of an asset's size to consider:

The size of each cast member's header information
For each cast member, Director loads a small header that describes its contents when the movie is first loaded. This header is completely separate from the media for the cast member, which may not be loaded until later. An excessive number of cast members (more than several thousand) can require significant RAM. Although media elements also require a lot of RAM, a cast member's media can be purged, but its header cannot. Likewise, the Score notation, shape cast members, and script cast members are all loaded when a movie or castLib is opened and are not purged until the movie ends. In D7, font cast members are also always loaded.

The size of a loaded asset's media in memory
The size shown in the Cast Member Info window (and by the size of member property) loosely indicates the amount of memory a cast member occupies if it is loaded (see the loaded of member). For cast members that point to other assets, such as film loops, #digitalVideo, and linked sounds, it represents the size of the cast member overhead or the #digitalVideo's header data. In such cases, the true size of the asset is usually much bigger than shown. The size of member reflects the disk file size for #QuickTimeMedia members.

Select multiple cast members and use Modify Cast Member Properties to view their cumulative size.

The size of an asset on disk
Whether in an internal or external castLib, or an external file, the time to load or download an asset is determined by its compressed size on disk which is smaller than its size once loaded into memory. There is no easy way to determine the size of internal cast members compressed on disk (see Example 9-1).

The data rate of streaming media
It is possible to play very large external video and sound files that exceed the available memory because they are streamed from disk in "chunks" that are discarded once played. When streaming data, the main concern is not the entire file's size, but its data rate (the amount of data per second that must be loaded). For example, a video compressed to 1 MB/sec requires more throughput than one compressed to 400 KB/sec. Likewise, a CD-quality audio file requires 176 K/sec of data, versus a 22 kHz, 8-bit, mono sound requiring only 22 K/sec. The data rate of uncompressed streaming media (standard audio files) depends on the characteristics of the original content (sample rate, number of channels, and so on). The data rate of compressed streaming media (digital video and Shockwave audio) is primarily determined by the compression settings and the desired fidelity.

Streaming data

The Modify Movie Playback option lets you specify how Director should handle streaming Internet media from within the Shockwave plug-ins within a browser. This also affects the playback of cast members at a remote URL linked into a Projector (streaming options vary slightly in D6 and D7).

Bitmaps and PICTs

Embedded (unlinked) bitmaps are converted to Director's internal bitmap format (unless imported as a PICT). Director's internal format is optimized for a balance between disk size and access speed. It uses RLE (Run-Length Encoding) compression. Large areas of the same color compress extremely well, and the number of unique colors in a graphic determines its size on disk. (A 16-bit graphic using 256 colors will compress to the same size as an 8-bit graphic using 256 colors.)

Once a bitmap is loaded, its uncompressed size in RAM can be much larger than the disk storage size. This is calculated (in bytes) as:

(the width of member) × (the height of member) × (the depth of member)/8

Thus, an 8-bit graphic uses one-quarter the RAM of a comparable 32-bit graphic. Bitmaps at a different depth than the monitor must be converted on the fly, which slows performance.

The RAM used by a bitmap depends on its bounding rectangle, so an L-shaped graphic that is 300 pixels on each side takes up the same RAM as a solid 300 × 300 graphic. Cut L-shaped graphics into two cast members to reduce the memory required by upwards of 75%. Likewise, a four-sided framing graphic with a large blank center would occupy much more RAM than four individual sides of the frame.

Linked bitmaps in formats such as JPEG and GIF tend to be smaller on disk but much slower to load, and occupy the same memory once loaded as another bitmap. Linked bitmaps are often so slow as to be unusable. I import bitmaps as unlinked even if I expect the artwork to change. PICT cast members retain their original PICT format and typically require less disk space and less memory, but are slower to load than standard bitmaps. D7 also supports internal JPEG- and GIF-compressed cast members. Import them using the Include Original Data for Editing option.

When creating animations, consider the number and size of bitmaps you will need over time and how fast they can be loaded from disk or the Internet.

Shapes, Vector Shapes, and Flash

QuickDraw shape cast members are incredibly efficient and occupy only 64 bytes, as indicated by the size of member property. Shapes using a fill pattern or custom tile are much more compact than an equivalent bitmap, although they take slightly longer to draw. A single shape can be stretched and colorized to create multiple sprites. Shapes are always loaded in memory, but this overhead is usually minimal.

Flash and D7's new vector shape cast members are vector-based graphics that require extremely low storage and RAM, but more processor power. Flash and vector shape members are supported on Win32 and Mac PPC systems only.

For information about the Flash Asset Xtra see the HTML help files included with D6.5, the D7 Help, Table 4-10, and http://www.zeusprod.com/nutshell/appendices/flash.html.

Buttons

There are two entirely distinct button types:

Standard buttons
Built-in Director push button, check box, and radio button cast members created with the Tool Palette occupy only about 250 bytes each.

Custom buttons
Custom Buttons are inserted via Insert Media Element Custom Button in D6. A Custom Button can contain up to eight states, each using a different graphic. The size of member property for Custom Button cast members depends on the size of the underlying bitmaps incorporated into it. Unlike film loops, those assets can be deleted once they are incorporated into the Custom Button. Leave unused button states empty to conserve memory. The Custom Button Xtra is obsolete in D7.

Fields

Field cast members are limited to 32,000 (not 32,768) characters in D6, and occupy between about 250 bytes and 35 KB (the character and size limit is eliminated in D7). This includes the cast member header, plus one byte per character, plus overhead for formatting (about 25 characters per style run).

To calculate the length of a field's contents, use:

put length (field whichFieldMember)
put the length of the text of member whichFieldMember

Field string manipulation can become egregiously slow if a string contains more than a few thousand characters. Copy the contents of a field to a string variable to perform string manipulations, then copy the result back to the field. String variables can contain strings up to about 2 MB, but they too can become slow at those sizes.

Formatted and colorized fields can be slow and may occupy much more memory than unformatted text. Keep the formatting simple.

Rich Text and Text

Rich text cast members in D5 and D6 are stored as bitmaps, and their size of member property depends mainly on the number of characters and point size. A typical rich text cast member may be from 2 KB to more than 200 KB (25 times larger than a comparable field cast member). Rich text cast members are not compressed when converted to Shockwave format. Prior to D7, convert rich text cast members to bitmaps for better compression, use field cast members (which are always smaller), or use the Flash Asset Xtra, which provides high-quality animated text at extremely low bandwidths. In D7, use the new text and font cast members (as described in Chapter 12), which are space-efficient.

Film Loops and Movie Cast Members

The size of member property for film loops is usually about 1 KB and does not include the cast members that make up the actual film loop. To determine their size, copy the film loop into the Score, and use the ramNeeded( ) function to determine the memory required for the range of frames comprising the film loop. See .

The size of member property for linked movie cast members is zero and does not reflect the size of the external movie file.

Palettes and Transitions

By using 8-bit custom palettes, you can reduce the RAM required for bitmaps substantially (see Chapter 13). Cast members using built-in transitions require 0 extra bytes. Third-party transition Xtras usually occupy very little memory, although some that use precalculated data may be larger.

Scripts

Script cast members are limited to 32,000 (not 32,768) characters in D6 (this limit is removed in D7), but their size of member property may be twice that (about 60 KB), because it includes the size of the compiled script. The original scriptText is stripped out of protected movies, which reduces the scripts' size by about half.

During authoring, you can calculate the length of a script's contents using:

put length (the scriptText of member whichScriptMember)

All the script cast members in a movie and its external castLibs are always loaded and never swapped out until the movie closes. Hundreds of scripts may occupy substantial memory.

Generalize your handlers or use Behaviors to reduce the number of scripts in a project. Refer to Chapter 1, How Lingo Thinks, and Chapter 12, Behaviors and Parent Scripts, in Lingo in a Nutshell for details.

Digital Videos

Digital videos are always externally linked and streamed from disk as they play, enabling a large digital video file to be played without requiring excessive memory. The size of member reflects only the size of a #digitalVideo member's header, but reflects the true external file size for #QuickTimeMedia members. Digital videos should be compressed using MediaCleaner (formerly MovieCleaner), Adobe Premiere, or a similar utility.

A video's average and peak data rates affect performance much more than the total overall size on disk. A video's average data rate can be calculated as:

 

A video's peak data rate is also of concern, although it is often not significantly higher than the average data rate. Use an external tool such as Adobe Premiere to check a movie's peak data rate. When budgeting for bandwidth, don't forget the size of the audio track(s) within the digital video file.

Sounds

A sound's memory requirements depend on its fidelity, whether it is compressed, and whether it is linked (external) or unlinked (internal). The size of a sound depends partially on the number of channels within the sound (1 for mono, 2 for stereo). See Chapter 15 for additional details and caveats about each type of sound.

Linked external sounds

Externally linked sounds are streamed from disk as they play, enabling a large sound file to play without waiting for it to load and without requiring excessive memory. Only enough memory to buffer the sound is required (usually less than 400 KB). The size of member as reported for linked sounds does not accurately reflect the size of the external sound file.

Unlinked internal sounds

Internal embedded sounds are always loaded into memory before being played, and are best limited to small (less than 500 KB) sounds. Large sounds should be externally linked, instead. Use looping sounds to reduce memory requirements. The size of member accurately reflects an internal sound's size and can be calculated (in bytes) as:

(samples per second) × (bits per sample/8) × (length in seconds )
× (number of channels)

For example, an 11 kHz, 8-bit, mono sound requires 11 K/sec, and a 44 kHz, 16-bit, stereo sound requires 176 K/sec.

Compressed sounds

Director supports IMA-compressed AIFF audio (4:1 compression). IMA-compressed sound cast members are not further compressed by Shockwave, even when Shockwave audio compression is activated. If Shockwave audio compression is disabled, LZW compression is used for other internal sounds in DCR and CCT files (about 30% savings).

Shockwave audio (SWA)

Naturally, Shockwave audio (SWA) compression is used for external SWA files, but it can be used for internal sound cast members with both Projectors and Shockwave (see the Xtras Shockwave for Audio Settings option). With SWA, you choose an output bit rate (target bandwidth), not a compression ratio. An SWA sound's download size can be calculated (in KB) as:

 

The MPEG-3 compression algorithm used by SWA yields higher quality sound without additional bandwidth when using a higher fidelity source. Always use either 22 kHz or 44 kHz 16-bit source audio for SWA compression.

Note that SWA sounds requires measurable processing power and may hinder performance on lower-level machines.

Xtras

The amount of memory required for Sprite Asset Xtras is highly dependent on the asset type. The Flash Asset Xtra provides excellent vector-based graphics at extremely low bandwidths and allows fine control over its memory use. Other Xtras, such as the QT3 Xtra, may use substantially more memory and/or use memory-intensive data types.

Determining Asset Sizes via Lingo

The size of member property reliably returns the RAM required for most internal cast members, including bitmaps, internal sounds, shapes, buttons, scripts, fields, and text cast members. It does not accurately reflect the RAM used by external sounds (SWA included), digital video, film loops, and movie cast members. Table 9-2 shows cast member properties useful in determining an asset's size.

You can check the size of an external file in the Finder or File Explorer during authoring. Refer to Example 4-6, which calculates an external file's size.

Table 9-2: Size-Related Member Properties

Media Type

Member Size

#bitmap

the depth, height, width, and size of member

#button

length(the text of member) and the size of member

#digitalVideo

the duration, frameRate, and preLoad of member, and the preLoadRAM; see Example 4-6

#field

length(the text of member) and the size of member

#filmLoop

the media of member (must be unwrapped)

#movie

see getSize( ) utility in Example 4-6

#picture (imported as PICT)

see getSize( ) utility in Example 4-6

#QuickTimeMedia

the size of member ; see the getSize( ) utility in Example 4-6

#richText

the size of member

#script

length(the scriptText of member) and the size of member

#sound (linked)

the channelCount, sampleRate, and sampleSize of member

#sound (internal)

the size of member

#swa

the bitsPerSample, sampleRate, numChannels, and duration of member

#text

length(the text of member) and the size of member

Data Throughput

When calculating the acceptable size of an asset, keep in mind the speed of the device (such as a CD) from which it will be loaded. The practical data rate is somewhat lower than the theoretical data rate for a CD-ROM. Table 9-3 shows the approximate time to load 5 MB of data from various CD-ROM drives. Remember that data is often compressed on disk, so that a 300 KB bitmap may require less than half that on disk. Thus, even a quad-speed CD-ROM may be able to load two full-screen (640 × 480 × 256-color) images per second. In practice, there may be some latency when first accessing data, due to Director having to find it on the CD-ROM.

CD-ROM performance can also depend on the driver and cache settings. The third-party CD-ROM Toolkit (by FWB) can alter Macintosh CD-ROM drive settings. Under Windows 95, see the System control panel (Performance tab File System button CD-ROM tab).

Table 9-3: CD-ROM Speeds

CD-ROM Drive

Theoretical Data Rate

Practical Data Rate

Load Time (5 MB)

Single-speed (1X)

150 KB/sec

100 KB/sec

50 sec

Double-speed (2X)

300 KB/sec

200 KB/sec

25 sec

Quad-speed (4X)

600 KB/sec

450 KB/sec

11 sec

Eight-speed (8X)

1200 KB/sec

900 KB/sec

4.3 sec

High-speed (>16X)

> 2400 KB/sec

> 2000 KB/sec

< 2.5 sec

Disk Capacity Budget

A typical CD-ROM holds about 650 MB of data. Table 9-4 shows how much data of a given type will fit on a single CD, but in practice, you will have a mix of various data types, plus some overhead for the installer, Projectors, Xtras, and so on. When using DVD-ROMs, which hold 4 GB or more, you can scale these figures accordingly. For many details on a variety of disc formats (and capacities), see the technical notes from Cinram at:

http://www.cinram.com/Techlibrary/technical_library.html
http://www.cinram.com/PDF/capacity.pdf
Table 9-4: CD-ROM Capacities

Asset Type

Storage Requirement

Fits on CD

Digital video (Cinepak--quarter screen)

400 KB/sec

27 minutes

Digital video (Cinepak--full screen)

1600 KB/sec

6.9 minutes

Digital video (Sorenson)

80 K/sec

135 minutes

MPEG-1 full-motion video

150 K/sec

74 minutes

MPEG-2 full-motion video

575 KB/sec

20 minutes

Audio (16-bit, 44.1 kHz, Stereo)

176 K/sec

64.5 minutes

Audio (16-bit, 22.050 kHz, Mono)

44 K/sec

4.3 hours

SWA (MP3) CD-quality

20 K/sec

9 hours

Bitmaps (640 × 480 × 256-color Director internal format)

200 KB/image[3]

3,300 images

Bitmaps (640 × 480 × millions of colors; JPEG compressed)

75 KB/image1

8,875 images

Director Memory Budget

Projectors require less memory than Director because they don't support many authoring-time features. Macromedia's Tech Note #03107, "Projector Memory Requirements," is woefully outdated and has several errors. The default preferred Macintosh Projector memory allocation may be adequate (see Table 9-1), but the default minimum memory allocation rarely is. Windows Projectors like to allocate at least 10 MB if it is available. Table 9-5 shows a possible memory budget for the Projector, exclusive of media elements. D7 recommends a minimum of 12 MB of RAM available for both Macintosh and Windows Projectors. I recommend a minimum 32 MB of real RAM installed, plus the virtual memory settings described earlier in this chapter.

Table 9-5: Program Memory Budget

Item

Mac

Win

Operating system[4]

5 to 10 MB

2 MB for Windows 3.1

8-24 MB for Windows 95/98/NT

Projector code

1 to 3 MB

1 to 3 MB

Projector misc. memory

1 to 3 MB

1 to 3 MB

Offscreen buffer[5]

300 KB or higher

300 KB or higher

Digital video drivers[6]

500 KB to 1.5 MB

500 KB to 1 MB

Xtras[7]

100 KB/Xtra

100 KB/Xtra

Browsers often require 15 MB of memory or more. See Table 11-2.

Table 9-6 outlines the memory requirements that depend directly on media usage. These are arbitrary numbers based on a typical project. You can estimate the RAM needed for your product by performing calculations as shown under "Media Sizes" earlier in this chapter. Internal bitmaps and sounds are usually the biggest consumers of memory. The QuickTime 3 Asset Xtra requires substantial additional RAM. Macintosh Projectors using QT3 may need 15 MB. Your actual requirements may vary widely depending on the nature of your project. Remember that Director will load and unload cast members as needed, so you can survive with less memory at the expense of performance. In extremely low memory, Director may drop out sound or graphics.

Table 9-6: Media Memory Budget

Item

Mac

Win

Score notation and cast member headers

100 KB to 1 MB

100 KB to 1 MB

Script cast members

100 KB to 1 MB

100 KB to 1 MB

Bitmaps and other cast members

2 MB to 3 MB

2 MB to 3 MB

Internal sound cast members

500 KB to 1 MB

500 KB to 1 MB

Digital video[8]

500 KB to 1 MB

500 KB to 1 MB

Streaming buffer for external sounds[9]

400 KB

2.5 × the size of one second of audio
(27 KB to 440 KB)

MIAW[10]

500 KB to 1 MB

500 KB to 1 MB

Offscreen Buffer

Director composites sprites in an offscreen buffer whose size depends on the dimensions of the Stage. The size of the offscreen buffer can be calculated (in KB) as:

 

For example, a 640 × 480 × 8-bit offscreen buffer requires a 300 KB. In D6, if the fullColorPermit is FALSE, the size of the offscreen buffer is treated as if the colorDepth is 8-bit. Millions of colors is considered 32-bit, though the colorDepth reports it as 24-bit under Windows. Larger Stage dimensions and higher color depths usually imply that bitmaps will require more RAM as well.

MIAWs also increase the size of the offscreen buffer. In D6, it appears that MIAWs share an offscreen buffer with the Stage under Windows but have their own offscreen buffer on the Macintosh. In D7, the Stage and MIAWs have separate offscreen buffers on both platforms.

Cast and Score data

Although the Score's notation is fairly compact, the entire Score is loaded into memory when a movie is loaded. The size of the Score data also depends on the number of sprite channels used and the frequency of changes in the Score. Join sprites and eliminate unnecessary keyframes to reduce the Score notation's size markedly (you can save 1 MB over a large, inefficient Score).

There is also overhead associated with each cast member and their thumbnails (although the latter are stripped out when protecting a movie). Split movies containing thousands of frame changes or cast members into multiple movies to reduce the RAM used for the Score and Cast during the life of a given movie.

Data Structure Memory Requirements

Lingo variables and the data they point to require varying amounts of memory, as shown in Table 9-7. Simple types (integers, VOID values, symbols, and floats) always occupy 8 or 16 bytes. Complex types (strings, lists, child objects, and Xtra instances) occupy 8 bytes plus additional memory that varies with the size of the structure (such as the number of characters in a string, or the number of elements in a list). You can free the memory used by a complex data type by setting it to simple value, such as VOID, but even a VOID item will occupy 8 bytes.

Table 9-7: Lingo Data Structure Memory Requirements

Item

Minimum Size

Max Size

Integer

8 bytes

8 bytes

VOID

8 bytes

8 bytes

Symbol[11]

8 bytes

8 bytes

Float

16 bytes

16 bytes

String

8 bytes + 1 byte per character

About 2 MB

List

8 bytes + size of elements

About 2 MB

Xtra instance

8 bytes + 180 bytes

No specific limit

Child object (script instance)

8 bytes + 180 bytes

No specific limit

Disposing of Objects (Freeing Memory)

All your variables combined may occupy less memory than a single bitmap. However, complex structures such as objects, strings, and lists can consume considerable memory and should be disposed of when no longer needed. Different types of objects are disposed of (freed) in different ways:

Variables
Local variables (those used within a single handler) are allocated when the handler is called and freed automatically when the handler terminates.

Property variables are allocated when the object, such as a Behavior script, parent script, or Xtra instance, is instantiated. They are freed when no variables refer to the object.

Global variables persist indefinitely, but by assigning a global variable to VOID, it occupies minimal memory. Avoid clearGlobals, which indiscriminately clears all globals as well as the actorList in D6 and D7. Use D7's new the globals property as described at http://www.zeusprod.com/nutshell/d7/globals.html to see a list of all globals currently allocated.

XObjects
Use mDispose to dispose of XObject instances and closeXlib to close XObject libraries. These are not for use with Xtras and are not supported in D7.

Xtra instances, child objects, lists, and strings
Set the variable pointing to the object to zero or VOID, such as:

set myInstance = 0

MIAWs
Use forget window to eliminate a MIAW from memory. Close window merely hides the window and does not release its memory. Clear any global variables, properties, and objects in use by the MIAW before disposing of it.

Movies accessed via play movie
Use play done to return from a movie that was accessed using play movie. The second movie's memory is not released until you return to the first movie using play done. Use go movie instead to reduce memory usage, as it immediately releases the old movie from memory.

Purgeable Items

Director loads and unloads many entities without your knowledge or instruction. The following items are purgeable if Director needs the memory:

The following items are never purged:

The following items are not purged until leaving the current movie:

Cast Member Loading and Unloading

Cast members must be loaded from the disk or the Internet before they can be used. There is always a performance "hit" (delay) when cast members are loaded. You can either manually preload the cast members (and tolerate the delay) before the animation starts or let Director load the cast members as they are needed (and tolerate multiple small pauses as the animation plays).

Optimization of loading will not help if you are demanding too much throughput--reduce your media requirements instead!

Implicit Loading and Unloading

You can control cast member loading in many ways, but regardless, Director will attempt to load cast members when it needs them to draw the current frame. Use Modify Cast Properties or Modify Movie Casts Properties to control cast member loading on a castLib basis. (These equate to the preLoadMode of castLib property.) The default setting (When Needed ) loads cast members on demand, whereas the Before Frame One and After Frame One modes attempt to preload as many cast members as possible (use these mainly for linear presentations on dedicated hardware).

Automatic cast member unloading and the purgePriority

Director unloads the least recently used cast members as required to make room for new ones. Other unused cast members may remain loaded in case they are needed at a later time. The Unload option in the Cast Member Info dialog box (corresponding to the purgePriority of member) controls cast member unloading. Normal items with the highest purgePriority (3) are purged first, followed by items flagged as Next (purgePriority = 2), and finally Last (purgePriority = 1).

WARNING:  

Don't use the Never Unload option (purgePriority = 0). It prevents Director from unloading assets even in desperate situations and can cause a crash.

Despite what Macromedia's older manuals and most third-party books erroneously imply, there is no "purge first" setting that purges cast members before Normal items. You must use unLoadMember explicitly to purge a cast member before other items.

The Unload setting is largely irrelevant for streamed assets, such as digital video and externally linked sounds, which are always discarded from memory as they are played. It is ignored for script, shape, transition, and font cast members, which are never unloaded.

Explicit Unloading

You can explicitly unload cast members using the commands in Table 9-8. The unload commands attempt to unload the cast members used in one or more frames of the Score, and the unLoadMember commands attempt to unload the specified cast members, but they may not be able to unload some of them for the reasons listed earlier. UnloadMember is buggy in D7.0, but fixed in D7.0.1.

Table 9-8: Unload Commands

Command

Usage

unload

Unloads only those cast members used in the Score.

unload fromFrame {, toFrame}

Unloads cast members in a range of frames, or in a single frame, if toFrame is omitted.

unload member fromMember, toMember

Unloads a range of cast members, as would the unLoadMember command.

unloadCast

Obsolete. See unLoadMember.

unLoadMember

Unloads all cast members in D6. In D7.0, but not D7.0.1, you must manually specify a range.

unLoadMember member fromMember {of castLib fromCast}, {member toMember of castLib toCast}

Unloads a range of cast members or a single cast member if toMember is omitted[12] (fromCast and toCast can be different castLibs).

unLoadMovie whichMovie

Unloads the specified movie (which can be a URL reference). The result returns 0 if successful or -1 if movie was not loaded.

Reader Exercise: Write your own utility to unload a list of cast members or create an "exclusive unload" utility to unload all cast members except those specified.

Analyzing Memory Usage and Cast Member Loading

Director can analyze memory usage and cast member loading to help you track and debug memory problems.

The Memory Inspector

Window Inspectors Memory opens the Memory Inspector windoid (shown in Figures 9-1 and 9-2), which shows the memory allocated to various uses and includes a Purge button that frees as much RAM as possible. Refer also to the Memory Inspector entry in the online Help. The appearance of the Memory Inspector varies across platforms and depends on the Use System Temporary Memory (Mac) and Limit Memory Size (Windows) options under File Preferences General. The values reported in the Memory Inspector are not always reliable, and the area of the bars in the graph are not necessarily to scale.

Figure 9-1. Memory Inspector (Macintosh)

 

Figure 9-2. Memory Inspector (Windows)

 

To determine the installed RAM, virtual memory, and available RAM accurately, use a third-party Xtra, such as Buddy API's baMemoryInfo( ) method or OSutil's OSGestalt( ) method.

The Memory Inspector displays the following values:

Total Memory
Installed physical RAM, plus virtual memory (if any).

Partition Size (Macintosh only)
Memory allocation set in the Finder's File Get Info window. Memory usage can exceed this if Use System Temporary Memory is checked under General preferences (or under File Create Projector options).

Physical Memory (Windows only)
Installed physical RAM only. Director can use virtual memory beyond the physical RAM.

Memory Limit (Windows only; not shown in Figure 9-2)
Reflects Limit Memory Size setting, if any, under General preferences.

Total Used
RAM currently in use for the offscreen buffer, Cast and Score notation, and mattes and thumbnails. This is not the total memory used by Director.

Free Memory (see the freeBytes in Table 9-9)
Unused memory available to Director. On the Macintosh, without Use System Temporary Memory enabled, it shows the unused portion of Director's fixed memory partition. On Windows, and on the Macintosh only when Use System Temporary Memory is enabled, it shows available system memory (including virtual memory).

Other Memory (shown on Windows, and on Mac if Use System Temporary Memory preference is checked)
RAM used by OS and other programs.

Used by Program
RAM currently used by Director. The value shown under Windows is completely wrong in D6.

Mattes & Thumbs
RAM used to create mattes and display thumbnails.

Cast and Score
RAM used to hold cast member and Score notation and edited cast members until they are saved to disk.

Screen Buffer
RAM used for offscreen compositing buffer. Size depends on the colorDepth and the Stage's dimensions.

Purge Button
Use this button to unload any items that are purgeable.

Determining Whether the Necessary Memory
Is Available

Table 9-9 lists the commands that analyze RAM and disk space.

Table 9-9: Memory and Disk Space Analysis Commands

Command

Usage

cacheSize newSize

put cacheSize( )

Gets or sets the cache size for downloadable media in a Projector or during authoring. Does not apply to Shockwave.

the fileName of member whichMember

Use this to locate the external file, whose size can then be determined using the FileIO Xtra. See Example 4-6.

frameReady ( )

Returns TRUE if the cast members required for the entire movie have been downloaded, or are local.

frameReady (startFrame
{, endFrame})

Returns TRUE if the cast members required for the specified frame or range of frames have been downloaded, or are local.

the freeBlock

Returns size (in bytes) of the largest contiguous block of RAM.

the freeBytes

Returns total size (in bytes) of RAM available to Director, including Temporary System memory and virtual memory, if applicable.

getStreamStatus (netID or URL)

Get status of specified netID or URL (new in D7).

the loaded of member whichMember

Returns TRUE if cast member is currently loaded.

the mediaReady of member

Returns TRUE if cast member has been downloaded, or is local.

the memorySize

Returns size (in bytes) of the RAM allocated to Director or the Projector. Additional memory may be available (see the freeBytes).

the modified of member whichMember

Returns TRUE if cast member was created or modified since movie was last saved.

the movieFileFreeSize

Returns disk space (in bytes) that can be recovered using File Save and Compact.

the movieFileSize

Returns the size on disk in bytes of the current movie. Does not include external castLibs.

netDone(netID )

Determines whether a network operation, including preloadNetThing, has completed.

the purgePriority of member whichMember

Affects Director's automatic unloading of cast members. Those members with a higher purgePriority are unloaded earliest.

ramNeeded (fromFrame, toFrame)

Returns amount of RAM needed for cast members in the given range of frames. Use the same starting and ending frame number to check ramNeeded for a single frame.

the size of member whichMember

Returns size of a cast member in RAM once it is decompressed from disk. Does not accurately reflect size of externally linked cast members.

the state of member swaMember

Returns "ready" if an SWA cast member has downloaded successfully.

tellStreamStatus (flag)

put tellStreamStatus( )

If flag is TRUE, Director will call the on streamStatus handler periodically, but if flag is FALSE (the default), it will not. If flag is omitted, tellStreamStatus( ) returns the current setting. See getStreamStatus( ).

set the traceLoad = 0|1|2

Determines whether cast member loading is shown in the Message window. Highly improved in D7.

set the traceLogFile = fileName | EMPTY

Setting the traceLogFile directs the output from the Message window to an external text file. Setting it to EMPTY closes the external file.

The FreeBytes, the FreeBlock, and RamNeeded( )

If the freeBlock is less than the freeBytes, RAM has become fragmented, which can happen when cast members of varying sizes are loaded and unloaded repeatedly. In this case, Director may thrash (repeatedly load and unload the needed cast members). Clear (and defragment) memory using unLoadMember as follows:

if the freeBlock < 200 * 1024 then
  unLoadMember
end if

The entry under ramNeeded in Macromedia's Lingo Dictionary includes an example that checks the ramNeeded( ) against the freeBytes to determine whether enough memory is available, but this is misleading. The ramNeeded( ) overstates the required memory if some cast members are already loaded (but understates the RAM needed if preloading digital video). Furthermore, the freeBytes understates the available memory, unless all purgeable cast members have been unloaded. To get accurate information, you must unload all cast members at the risk of having to reload some of them.

Reader Exercise: Write a frameLoaded( ) utility that checks whether the cast members needed for a frame are loaded. Model its syntax after the ramNeeded( ) and frameReady( ) functions. (Hint: use the loaded of member property to check each sprite's cast member. Use go frame to move the playback head so that you can check frames other than the current frame.) FrameReady( ) is not helpful because it indicates only whether items are available locally, not whether they are actually loaded.

The traceLoad

The traceLoad can diagnose loading problems by displaying in the Message window those cast members that are being loaded. It has three possible settings:

0:

No output (the default). Loading is not shown.

1:

Shows the cast member name or number of cast members being loaded.

In D6:

preLoadMember 200, 201 Loaded cast 200 Loaded cast Roulette Wheel

In D7:

member 200 of castLib 1("Roulette Wheel") was loaded into memory

2:

In D6, shows the cast member name or number, current frame, current movie, and file seek offset of cast members being loaded, such as:

Loaded cast 200 frame=1 movie=Test seekOffset=-598

In D7, in addition to the information shown when the traceLoad=1, the traceLoad=2 shows:

Time = 1470997 msec (237 msec later) Movie "test" is on frame X (freeByes = 26616908, 49200 bytes consumed) Member is in movie (or external castLib) "filename" File Seek Info: No file access occurred File Seek Info: Seeked between files! Seeked 9014 to final member at filepos 19262. Read in 4404 bytes.

WARNING:  

Using the traceLoad=2 will crash D7.0 unless you first save the movie and any castLibs. This bug is fixed in D7.0.1.

In D6's traceLoad output, the Loaded cast indicates only the cast member's memberNum, not its castLibNum. The frame is the current frame, not the frame of the Score for which the cast member was loaded (so it is useless when performing explicit loading via Lingo). The movie is the internal or external castLib's name. The seekOffset indicates the distance that Director had to seek (forward or backward) in the file to find the requested cast member. Large seek offsets imply that the cast members are stored inefficiently. Perform a File Save and Compact before using the traceLoad to diagnose file seek problems.

In D6, the traceLoad 's output does not show cast members being unloaded, nor does it show cast members that are already loaded. Set the traceLogFile to capture the output to an external text file for later analysis.

In D7, unloading is shown as:

member X of castLib Y ("Name") was purged from memory

Determining the compressed size on disk

In D7, use the traceLoad=2 to analyze disk usage for cast members. In D6, you can't easily tell the size or relative positions of cast members in the Director movie file on disk. Example 9-1 uses the seekOffset from the traceLoad output in D6 to estimate the disk size of a cast member.

Example 9-1: Guessing an Asset's Size on Disk

on checkSeekOffset whichMember
  unLoadMember whichMember
  preLoadMember whichMember
  set the traceLoad = 2
  unload member whichMember
  preLoadMember whichMember
end

The result in the Message window will be something like:

Loaded cast x  frame=1  movie=test  seekOffset=-76718

The first preload positions the disk head at the end of the cast member. The second preload forces Director to seek back to the beginning of the cast member. The absolute value of the seekOffset is the approximate size of the asset on disk.

Determining what is loaded

The utility in Example 9-2 reports which cast members are loaded and how much memory they occupy. You may want to save the Director movie and unload all cast members before running showLoaded.

Example 9-2: Determining Currently Loaded Cast Members

on showLoaded startCastLib, endCastLib
  if startCastLib = void then
    set startCastLib = 1
  end if
  if endCastLib = void then
    set endCastLib = the number of castLibs
  end if
  -- Track count and memory used for various member types
  set memberCount   = 0
  set memSize       = 0
  set scriptCount   = 0
  set scriptMemSize = 0
  set modCount      = 0
  set modMemSize    = 0
  set neverCount    = 0
  set neverMemSize  = 0
  -- Look in all castLibs for loaded cast members
  repeat with x = startCastLib to endCastLib
    repeat with y = 1 to the number of members of castLib x
      -- If a cast member is loaded, try to determine why
      if the loaded of member y of castLib x then
        set thisSize = the size of member y of castLib x
        set memSize = memSize + thisSize
        set memberCount = memberCount + 1
        set thisType = the type of member y of castLib x
        case (thisType) of
          #script:
            -- Scripts are always loaded
            -- Don't bother printing them out
            set scriptCount = scriptCount + 1
            set scriptMemSize = scriptMemSize + thisSize
          otherwise:
            if the modified of member y of castLib x then
              -- Not unloadable because it has been
              -- modified since movie was last saved
              set append = "(MODIFIED)"
              set modMemSize = modMemSize + thisSize
              set modCount = modCount + 1
            else if the purgePriority of member y ¬
              of castLib x = 0 then
              -- Not unloadable because it is
              -- set to Never Unload
              set append = "(NEVER UNLOAD)"
              set neverMemSize = neverMemSize + thisSize
              set neverCount = neverCount + 1
            else
              -- Not unloaded because it is one of the other
              -- unloadable types (shapes, transitions, fonts)
              set append = EMPTY
            end if
            put member y of castLib x && "Type:" && ¬
                  thisType && append
        end case
      end if
    end repeat
  end repeat
  -- Display some statistics about what is still loaded
  put "Total size of" && memberCount && ¬ 
       "loaded member(s):" && memSize / 1024 && "KB"
  put "Including" && scriptCount && "script(s) totaling:" ¬
       && scriptMemSize / 1024 && "KB"
  put "Including" && modCount && "modified member(s)" && ¬
       "totaling:" && modMemSize / 1024 && "KB"
  put "Including" && neverCount && "unpurgeable" && ¬
       "member(s) totaling:" && neverMemSize / 1024 && "KB"
end showLoaded

Manual Preloading

Director allows you to attempt to preload cast members manually from disk into memory. Preloading stops when memory is full, so not all preload attempts succeed completely. Preloading cast members that are not ultimately needed is counterproductive, as is preloading additional cast members after memory is full (items preloaded in the first batch would be unloaded to make room for the second batch). Manual loading of cast members works best when sufficient memory is available and the preloaded members will be used imminently.

Manual preloading does not appear to be working correctly in D7.0. Upgrade to D7.0.1, which remedies several preloading bugs.

Preloading large amounts of data can be time-consuming. Set the preLoadEventAbort to TRUE to allow the user to interrupt preloading, or set the idleLoadMode to use idle loading as described Table 9-11. The preload commands do not generally preload externally linked files. Digital video files are preloaded only if the preLoad of member is set. SWA files are preloaded according to the preLoadTime of member property using the preLoadBuffer command.

The preloading commands shown in Table 9-10 return a status in the result that is of dubious value in determining whether they succeeded. Entries preceded by "the" are properties, not commands.

Table 9-10: Preloading Commands

Command

Usage

downloadNetThing URL, localFile

Downloads data from URL, so that it is local when needed.

preLoad toFrame

In D6 and D7.0.1, preloads all cast members used in the Score from the current frame to frame toFrame. In D7.0, use preload the frame, toFrame instead.

preLoad fromFrame, toFrame

Preloads all cast members used in the Score from frame fromFrame to frame toFrame.

preLoad member fromMember, toMember

Preloads a range of cast members, as would the preLoadMember command.

the preLoad of member videoMember

Determines whether a #digitalVideo or #QuickTimeMedia cast member's external video file can be preloaded. See the preLoadRAM entry.

preLoadBuffer member swaMember

Preloads a portion of an SWA as set by the preLoadTime of member.

preLoadCast

Obsolete. See preLoadMember.

the preLoadEventAbort

If TRUE, allows a mouse click or key press to abort preloading. Defaults to FALSE.

preLoadMember

Preloads[13] all cast members in the current movie in D6. In D7, it preloads only the first castLib.

preLoadMember member fromMember {of castLib fromCast}, {member toMember of castLib toCast}

Preloads1 a range of cast members, or a single cast member if toMember is omitted (fromCast and toCast can be different castLibs in D6, but preloading across multiple castLibs fails in D7).

the preLoadMode of castLib whichCast

Determines whether cast members are loaded when needed, or preloaded when the movie starts.

preLoadMovie whichMovie

Preloads a movie (URLs allowed) in anticipation of using go movie or play movie. The result returns 0 if successful or a negative error code.

preloadNetThing (URL)

Asynchronously preloads an HTML, GIF, or other web-based asset. Check the status with netDone( ).

the preLoadRAM

Specifies RAM (in bytes) used for preloading digital videos whose preLoad of member property is TRUE. When set to 0, all available RAM is used.

the preLoadTime of member swaMember

Determines the amount of sound preloaded (in seconds) when using preLoadBuffer or otherwise loading an SWA cast member.

the result

Used to access the result of a preload operation.

preLoadMember and preLoad

There may be insufficient memory to preload the cast members as requested via the preLoad and preLoadMember commands. Both return a status via the result that ostensibly can be used to check whether the operation succeeded. The following discussion applies mainly to D6. At press time, D7.0's preloading was too buggy to test effectively and D7.0.1 was not yet finalized.

preLoad and preLoadMember attempt to preload cast members in the order in which they are saved in the movie file or external castLib on disk, and not in memberNum order or the order in which they appear in the Score. Cast members are loaded from the lowest numbered castLib first.

The sequential cast member loading order is efficient when reading from disk, but leads to this oft-repeated potentially incorrect Lingo code:

preLoadMember 1, 5
put the result
-- 4
if the result < 5 then alert "Not enough memory to preload"

If cast members are used in the Score in the order 1, 2, 3, 5, 4, they will be stored to disk in the same order. The result will return 4 (the last cast member loaded), and not 5 (the highest numbered cast member loaded), implying an error, when in fact the preLoadMember command succeeded! (The result would return cast member 4, even if member 4 was already loaded, because the result indicates the last cast member that would be loaded if needed. It does not necessarily return the highest number member loaded, nor the member that was actually loaded last.) To make the result return a meaningful answer, use Modify Sort Usage in Score and then use File Save and Compact for internal casts. The sort order doesn't matter for members in external castLibs, because they are stored on disk in the order in which they appear in the Cast window.

Furthermore, if you preload frames 1 to 10, and the Score contains references to both internal and external cast members, members in the lowest number castLib are always loaded first. That is, if you need member 5 of castLib 2 in frame 1 of a movie, it may not be preloaded until after member 1 of castLib 1, even if the latter is not used until frame 2 of the movie! These issues may be more pronounced in Shockwave, where preloading can be slower.

If you attempt to preload items in smaller chunks, it is possible that those items preloaded with the first preload command will be unloaded by a subsequent preload command. In other words, preloading works best when you perform only one preload before using the newly loaded cast members. You can also unload all cast members before a series of preloads to increase the chance that your new cast members won't be unloaded.

The result of a preLoadMember command returns only the cast member's memberNum, leaving its castLibNum ambiguous:

preLoadMember member 2 of castLib 1
put the result
-- 2
preLoadMember member 2 of castLib 4
put the result
-- 2

Check the loaded of member property to confirm which cast members were loaded.

The preLoad command sets the result to the number of the last frame for which cast members were successfully preloaded, such as:

preLoad 1, 10
if the result <> 10 then alert "Couldn't finish preload"

Preloading digital video

A digital video's external data is not preloaded unless the Enable Preload option is set in its Cast Member Properties dialog box (or via the preLoad of member property). The preLoadRAM property determines the amount of memory used for preloading digital videos. The default setting (0) uses all available memory. Refer to Chapter 16, Digital Video, for more details on proper digital video preparation and optimizing digital video performance in Director.

If a digital video's data rate is sufficiently low, there should be no need to preload data, which should be provided on the fly. One exception might be a very small digital video that must play smoothly without dropping frames. To avoid accessing a CD-ROM in two places at once, preload animations or sounds instead, as they tend to be smaller than digital video.

The example for the preLoadRAM in Macromedia's Lingo Dictionary prior to D7 was meaningless. You should either specify a fixed value for preloading digital video, such as:

set the preLoadRAM = 2 * 1024 * 1024 -- 2 MB

or specify a percentage of the freeBlock for preloading, such as:

set the preLoadRAM = 0.5 * the freeBlock

The optimal setting would depend on the length of the video, the video's data rate, the free RAM, and the speed of the drive providing the data, but I prefer not to preload videos at all.

Asynchronous and Idle Loading

Typically, you might preload cast members for a segment in the Score and then wait a considerable time for the user to move onto the next screen. Director will generate one or more idle events during each frame as time allows. For example, if the Score's tempo is 10 fps, each frame is allotted six ticks. If Director takes only two ticks to draw the frame, 4 ticks would be left to process idle events. Director's idle loading commands (shown in Table 9-11) load cast members without monopolizing Director's attention.

Idle loading works in conjunction with the preLoad commands listed in Table 9-10. The frequency and duration of the attention paid to idle loading is controlled by the idleLoadMode, idleHandlerPeriod, idleLoadPeriod, and idleReadChunkSize properties.

The frequency of mouseEnter, mouseLeave, and mouseWithin events also depends on the idleHandlerPeriod. If the idleHandlerPeriod is not zero, rollover event handling becomes unusably sluggish.

Table 9-11: Idle Loading

Command

Usage

cancelIdleLoad loadTag

Aborts preloading of cast members with the specified loadTag.

finishIdleLoad loadTag

Finishes preload command previously tagged by loadTag.

on idle

The on idle handler is called during each idle event, but need not be used for idle loading.

the idleHandlerPeriod = numTicks

Increasing the idleHandlerPeriod reduces the frequency with which the idle, mouseLeave, mouseEnter, and mouseWithin events are generated. (Default is 0 in D6, which sends these events as frequently as possible and 1 in D7, which reduces Director's monopolization of the processor.)

idleLoadDone(loadTag)

Returns TRUE if cast members with specified loadTag are all loaded.

the idleLoadMode

Optionally allows idle loading (default is Never). See the next section.

the idleLoadPeriod = numTicks

Increasing the idleLoadPeriod increases the time between idle loads, allowing more time for idle activities other than cast member loading.

the idleLoadTag = loadTag

Creates an arbitrary loadTag that identifies the batch of cast members loaded by the next preload command.

the idleReadChunkSize = chunkSize

Size (in bytes) of data read each time idle load queue is serviced. Defaults to 32,767 bytes (32 KB).

The idleLoadMode

The idleLoadMode has four possible values:

0:

Cast members are immediately preloaded when a preLoad command is issued. (No idle loading. This is the default.)

1:

Performs idle loading when there is free time between the enterFrame and exitFrame messages in a frame.

2:

Performs idle loading each time Director calls the on idle handler. The idleHandlerPeriod limits how often idle events will be sent (the default is as frequently as possible) and the idleLoadPeriod determines whether Director will attempt multiple idle reads during an idle event (the default is to load as frequently as possible during an idle event).

3:

Performs idle loading as frequently as possible (both while idling in a frame, and again after exiting a frame before reaching the next frame).

Each time the idle load queue is serviced, Director reads data equal in size to the idleReadChunkSize (defaults to 32 KB).

If you expect the user to follow a particular path, you might preload the cast members used in a range of frames. Example 9-3 shows how to initiate and then wait for idle loading.

Example 9-3: Idle Loading

on exitFrame
  -- Idle load as frequently as possible
  set the idleLoadMode = 3
  -- Identify this idle load batch with an arbitrary number
  set the idleLoadTag = 1
  -- Idle load the next scene in the Score
  preLoad marker(1), marker(2)
end

Then, in a subsequent frame, you might wait for idle loading to complete before jumping to the new marker:

on exitFrame
  if idleLoadDone(the idleLoadTag) then
    -- Turn off idle loading.
    set the idleLoadMode = 0
    -- Go to next marker if all cast members are loaded.
    go marker (1)
  else if the mouseDown then
    -- Finish idle loading if the user clicked the mouse.
    finishIdleLoad (the idleLoadTag)
    set the idleLoadMode = 0
    go marker(1)
  else
    go the frame
  end if
end

Note that we left the idleHandlerPeriod, the idleLoadPeriod, and the idleReadChunkSize at their default values, causing idle reading to occur in 32 KB chunks as frequently as possible.

Memory Optimization

The following sections help you avoid and diagnose memory problems.

Before you can fix a memory problem, you must confirm that the problem is memory-related. The following conditions may indicate a lack of available memory but may also have other causes:

Causes of Memory Errors

There are two types of so-called memory errors: either Director is running low on memory due to a known limitation, or there is an unintentional memory leak in one or more system components. Director may issue the error, "Warning! The current movie has used all of Director's main memory and some of its reserve memory," or even crash. Save your file immediately if you receive this error.

Not enough memory

You can allocate more memory to Director as described under "Memory Allocations" earlier in this chapter. The following will often lead to low memory situations:

Importing or creating too many cast members during authoring or at runtime
Allocate more memory to Director, import fewer items, and resave the Director file to free memory. Avoid importing during runtime, or link to external files using the fileName of member property instead.

Cast members can not be unloaded
Save the file to allow cast members to be purged. Don't set the purgePriority of member to 0 (Never ). Use Normal, Next, or Last settings instead.

Director is trying to load a nonexistent cast member
If Director gives the error, "Not Enough memory to load some cast members," it may be trying to load a nonexistent cast member, caused by an erroneous reference in the Score to a cast member that has been deleted. See the traceLoad later in this chapter and Example 3-9 to diagnose the problem.

External applications are not leaving enough RAM available to Director
Quit other applications before starting Director or a Projector, and check the memorySize and the freeBlock.

Director does not leave external applications enough memory to be launched using the Lingo open command
Use zLaunch (http://www.zeusprod.com/products/zlaunch.html ) to quit the Projector while an external application runs and relaunch your Projector when the external application terminates.

Recursion
Recursion occurs when a handler calls itself or two routines call each other, either directly or indirectly. It often leads to a crash and should be avoided, unless it is intentional. In Example 9-4, the two functions call each other until Director runs out of memory due to an overflowed handler call stack. Set breakpoints in each handler to watch the call stack grow in the upper-left pane of the Debugger window (save your work first, as this may crash your computer).

Example 9-4: Bad Mojo Recursion

on handlerA
  handlerB()
end
 
on handlerB
  handlerA()
end

Memory leaks

The following are possible causes of memory leaks. Small leaks may never accumulate to the point where they cause trouble. You many need to test for a long time on a machine with little RAM to duplicate the problem. Not all of these things will always cause leaks. but if you suspect a memory leak, you should check these items first:

Using Lingo improperly or not freeing objects
An apparent memory leak may be caused by instantiating an Xtra or child object, creating a large list, or opening a MIAW but never disposing of it. You must eliminate references to objects to allow Director to perform "garbage collection."

A bug in or improper use of an Xtra or XObject
Try to isolate the cause of the problem and contact the Xtra manufacturer for instructions on proper use of the Xtra or to identify known bugs. Leaks from Xtras or XObjects are not uncommon, because C programmers must allocate and deallocate memory explicitly. Multiple layers, such as the ActiveX Xtra interfacing with an ActiveX control, increase the potential sources of error.

Cursor and menu leaks
Switching cursors in D6.0 caused a memory leak (although fixed in D6.0.1, it reappeared in D7.0, but should be lessened in D7.0.1). Switching menus repeatedly under Windows caused a severe memory leak in D5, and it is still recommended that you not switch menus or cursors excessively.

External castLib leaks
There have been reports of Sprite Xtras used in external Casts causing memory leaks. When in doubt, internal Casts are least likely to cause problems.

Sounds not being unloaded
Playing a puppet sound from an external castLib as you go to a new Director movie may cause the sound to stay in memory and never be unloaded (see http://www.updatestage.com/buglist.html ). Unpuppet any sounds (using puppetSound 0 ) before going to a new movie.

Using play movie without play done
When using the play movie command, the first movie is kept in memory until you return from the second movie using play done. Avoid the play movie command if you can't guarantee that a matching play done command will eventually be issued. Use go movie and a global variable to store the name of movie to return to instead.

Creating or importing assets dynamically at runtime
Any items created dynamically must reside in RAM. During authoring, these can be purged only when the Director file is saved. From a Projector, they can cause memory to run low. Avoid dynamic linking of content or set the fileName of member property instead.

External applications
Anything that uses an external application relies on that application to behave properly. If that external application leaks memory, you won't find the error within your Director project.

External files
When using external files, such as with the FileIO Xtra, close any files when done to allow the OS to deallocate the file handle assigned to the file.

Isolating and Diagnosing Memory Problems

Director performs memory cleanup ("garbage collection") periodically. There is a lag between when Director could reclaim memory and when it actually does reclaim it. Decreased available memory does not necessarily indicate a memory leak. Director won't unload cast members unless it needs the memory for something else or until you use unload or unLoadMember. The freeBytes and the freeBlock typically drop very low, and then fluctuate at low levels as Director unloads just enough cast members to make room for those it is about to load. In D7, the freeBytes shouldn't drop below 300 KB or so.

If memory decreases slowly over time, it may be the cumulative effect of a small memory leak. If memory drops suddenly and can't be reclaimed, it may be due to a large cast member not being freed from memory.

When you suspect a memory leak, try disabling any Lingo that performs any unusual and/or very repetitive operation. For example, if a project using an untested Xtra or unsupported Lingo command is leaking memory, disable those items first. Other suspicious items include dynamically editing properties at runtime that are ordinarily only changed during authoring. This would include changing member properties (as opposed to sprite properties), creating new cast members, Score recording, dynamically linking to external castLibs, and the like.

Use Alex Zavatone's MemMon utility to help diagnose memory problems. For the shareware version, search for "MemMon" at: http://www.director-online.com/help_central/DOUGsearch/searches/DWdemo.html. For technical and ordering information for the professional version, see http://www.blacktop.com/zav/toolkit. For Zav's article on memory management, see http://www.director-online.com/howTo/UD_articles/UD26.html.

Checking cast member loading and unloading

To display cast member loading, set the traceLoad in the Message window and play the movie:

set the traceLoad = 1

If a cast member reference is incorrect, you will see Director repeatedly try to load the problematic cast member that it can't find.

Check for purgePriority of member settings other than 3 (Normal ) or 2 (Next) using a loop similar to that shown in Example 4-8. Use the loaded of member property to determine which cast members are currently loaded (see Example 9-2).

Checking memory usage

Director has several commands to check memory usage. You should save your file, then select an empty Score frame, and use unLoadMember or the Purge button in the Memory Inspector to clear memory. Use put the freeBytes and put the memorySize to establish a baseline for the available memory.

Create an on idle handler that displays the available memory in the Message window or in field cast members you've placed on the Stage (see Example 9-5).

Example 9-5: Idle Handler Displaying Memory Status

on idle
  put the freeBlock into field "FreeBlock Display"
  put the freeBytes into field "FreeBytes Display"
  put the memorySize into field "MemorySize Display"
end

At any time you should be able to recover some or all of the memory used by selecting an empty Score frame and using unLoadMember. If memory continues to decline, there may be a leak.

WARNING:  

If writing to the Message window to diagnose a memory leak, be aware that each character displayed in the Message window consumes one byte of memory itself!

The diagnostic text printed in the Message window is purged when it exceeds 32 KB, but can appear to indicate a small memory leak when none exists.

Reducing Memory Requirements

Before allocating more memory, try to reduce the memory and bandwidth requirements for your project. Note that many of the following techniques improve performance as the memory use is reduced, which isn't surprising. On the other hand, using bitmaps instead of Flash vector sprites improves performance at the expense of memory usage. Options to reduce memory and bandwidth include:

Performance

Many developers discover that their titles that ran fine from the hard drive perform poorly when they run from a CD-ROM or on a slower machine. You should have a minimum-capability test box available to you in all circumstances. Refer to Chapter 7, Cross-Platform and OS Dependencies, for additional details on how the machine configuration can affect performance and intonations of the "Test Early, Test Often" mantra.

See "Determining the Appropriate Minimum Hardware Playback Platform" at http://www.macromedia.com/support/director/how/expert/playback/playback.html, and also http://www.zeusprod.com/technote/machspec.html. These articles discuss how to target the appropriate segment of the installed base to meet both your technical and marketing requirements.

Most developers create a project ad hoc and then see if it runs. You should instead design your project with the optimization principles discussed throughout this book in mind. This will reduce the likelihood and severity of any problems.

Often, a customer will report that your beta version does not run satisfactorily on his machine. Ideally, you can test it yourself on the customer's machine(s) in his presence. If this is impossible (and not just impractical) you must get the customer to tell you precisely which portions are unsatisfactory and the characteristics of the test machine. It is nearly impossible to diagnose and debug a problem that you can't replicate, and you won't know whether you've solved it until the client performs another round of testing. This is egregiously inefficient. Your goal should be to minimize the retesting cycle by installing Director on the machine(s) demonstrating the problem. If you don't see the problem on your test machines, obtain a machine with a comparable--preferably identical--configuration.

If necessary, you can simulate a crippled machine by removing RAM, running a CD-ROM over a network, running other applications at the same time, or using much larger versions of the media (such as 44 kHz, 16-bit, stereo sound) and playing back at higher color depths. You can also limit the amount of RAM in use by a Macintosh Projector or by Director during authoring as described earlier in this chapter. This may place enough of a load on Director that you can see the problems the client describes.

Refer to Chapters 12 through 16 to ensure that you've prepared your content optimally, as improper content preparation often contributes to poor performance.

Macromedia TechNote #08151, "Why does the NT CPU monitor go to 100% when I run Director?", provides excellent details on Director's requests for CPU time under Windows. Director soaks up all available idle events. This avoids potentially jerky animation caused by infrequent attention. Director only appears to consume 100% of the processor, because the Windows NT CPU meter measures idle event usage only by applications, not the system. Director does not prevent other applications from receiving time slices when needed. See the D7 ReadMe for more information.

Gauging Performance

You can measure the speed of a given operation by starting a timer with startTimer, and then checking the timer after the operation completes. Example 9-6 checks the speed of 1,000 executions of the offset( ) function. It could be used to compare processor performance or determine whether a particular Lingo command is relatively slow.

Example 9-6: Gauging Performance

on testSpeed
  startTimer
  repeat with i = 1 to 1000
    -- Test the offset() function
    set dummy = offset ("st", "test")
  end repeat
  put "Test took" && the timer && "ticks"
end testSpeed

Don't include a put statement within your timing loop because printing to the Message window is very slow. Store the result in a variable and print it after the timing test completes.

You can also start a timer in one frame, check it in a later frame, and then divide by the number of frames to calculate the approximate frame rate achieved when the movie runs.

Things That Hurt Performance

The following sections list optimization techniques. In some cases, you may need to specify a faster minimum playback platform with more memory and a faster CD-ROM or Internet connection.

Poor performance is often due to a confluence of factors or the cumulative weight of techniques that may not compromise performance in isolation. For example, if you are using SWA sounds, streaming high bandwidth video, and loading large graphics all at once, the cumulative load will overpower low-end machines. Using a high color depth and sprites with alpha channels adds insult to injury. Likewise, eliminating a single culprit may not improve performance measurably, but the cumulative benefit of small changes can be great.

Do not expect optimal performance from versions of Director that predated a given operating system. For example, you should consider upgrading to D7 if you are supporting Windows 98. If you encounter performance problems, perform tests with the latest version of Director.

Lingo scripting techniques or inherent Lingo sluggishness

Following are some Lingo performance tips. Some improve your Lingo code's readability; others compromise it for maximum performance (include comments in your Lingo as necessary):

Media and disk access

There are dozens of reasons why media or disk access might go awry. Here are some common problems:

Digital video

Digital video performance depends primarily on the proper creation of the digital video file in your digital video editing software and proper compression. Some tips to eliminate performance-robbing culprits:

Sound

Tips on sound optimization and reducing latency (see also Chapter 15):

Score, Cast, and window usage

There are a number of non-intuitive quirks to Director that can degrade performance:

TIP:  

To check whether a sprite or Effects channel is degrading performance, use the Mute button in the Score to disable that channel (including sound channels) temporarily.

Graphics and animation

Graphics and animation are at the heart of Director, and a common performance bottleneck:

Lingo Affecting Performance

There are several commands that affect how Director allocates CPU time. Refer to Chapter 11 for details on asynchronous operations (such as waiting for media to be downloaded from the Internet).

The cpuHogTicks

The cpuHogTicks affects how often Director for Macintosh allows other processes to obtain the processor's attention. It has no effect under Windows, and has been available (although undocumented) since Director 4. The default value (20) allows other processes to interrupt Director every 20 ticks (three times per second). It can be increased (judiciously) to avoid releasing CPU control in the middle of an operation. It will not increase performance as much as it will prevent an operation from being interrupted, and therefore provides smooth animation without an intermittent hitch.

The marginal performance benefit from increasing the cpuHogTicks is no substitute for proper optimization. It can also interfere with mouse, clock, keyboard, network, and other system events.

Set the cpuHogTicks to 0 to speed auto-repeating keyDown events while holding down a key.

The idleHandlerPeriod

The idleHandlerPeriod determines how often Director allows idle events to be processed. If the idleHandlerPeriod is increased from the default (0 in D6, and 1 in D7) idle events are processed less frequently. Set the idleHandlerPeriod to 0 to allow Director to monopolize the processor. Anything that depends on idle events, including the on idle handler, idle loading, and mouseEnter, mouseLeave, and mouseWithin events can become unusably sluggish at higher values.

The netThrottleTicks

The netThrottleTicks affects how often Director for Macintosh allows network operations to be interrupted. It is officially supported in D7, but was undocumented in D6. It has no effect under Windows or in Shockwave. The default value is 15 ticks (which allows net operations to be interrupted four times per second). Lowering the netThrottleTicks causes Internet-based media to download somewhat faster. Increasing the netThrottleTicks gives priority to local operations such as animation.

The fullColorPermit

The fullColorPermit determines the color depth of the offscreen buffer. To improve performance, set it to FALSE when using 8-bit graphics on monitors with a higher color depth. It is obsolete in D7.

The lastChannel

D7 allows up to 1000 sprite channels, but this degrades performance. Set the lastChannel to the smallest number of sprite channels you need under Modify Movie Properties. It is not settable via Lingo.

The useFastQuads

This undocumented D7 property renders sprites distorted with the new quad of sprite property more quickly but with lower quality. The default is FALSE. Setting it to TRUE also remedies some display bugs in D7.0.

The Big Squeeze (Fitting Your Project on a Floppy)

You'll often want to distribute a portfolio or demonstration piece on a floppy. That is becoming increasingly unrealistic as well as unnecessary. The compromises and time required to fit things on a floppy are rarely warranted these days. To wit:

If space is at a premium:

 


1. A PowerMac running a Standard (68K) Macintosh Projector uses the default memory specifications for a 68K Mac regardless of its VM setting.

2. The minimum and preferred memory allocations with VM turned off vary slightly depending on the Projector type and Xtras bundled within it.

3. A subjective approximation based on typical images with typical compression.

4. The size of the operating system depends heavily on the extensions loaded.

5. A 640 × 480 × 256-color (8-bit) Stage requires a 300 KB offscreen buffer.

6. The size of QuickTime on the Macintosh varies with the version and the QuickTime plug-in components installed and used. For example, the first addition of a QuickTime cast member increases the System memory usage by about 650 KB. Under Windows, it is possible, though unusual, to have a project that uses both Video for Windows and QuickTime for Windows.

7. This is a very rough estimate, but each Xtra regardless of its type (Scripting, Sprite Asset, Transition, MIX, etc.) consumes a small amount of RAM. Ship only the Xtras you need with your Projector.

8. Per typical 400 KB/sec video played concurrently. If the preLoad of member is enabled, see the preLoadRAM.

9. Per concurrent sound streamed.

10. Arbitrary estimate per MIAW. Exact RAM depends on size and complexity of MIAW.

11. Symbols always persist for the life of Director or the Projector. See Lingo Symbol Table Archaeology at http://www.zeusprod.com/nutshell/chapters/symtable.html.

12. UnLoadMember requires that fromMember and toMember be valid member names or numbers. Use the number of members of castLib property to find the last valid member.

13. PreLoadMember requires that fromMember and toMember be valid member names or non-empty member slots. The number of members of castLib property returns the last valid member slot, but that slot may be empty if cast members have been moved or deleted. The number of castLibs returns the number of the last castLib.

Back to: Sample Chapter Index

Back to: Director in a Nutshell


O'Reilly Home | O'Reilly Bookstores | How to Order | O'Reilly Contacts
International | About O'Reilly | Affiliated Companies

© 2001, O'Reilly & Associates, Inc.
webmaster@oreilly.com