>Are you saying that I should check for memory required to load a form,
>for example, before loading the form?
Looking through the PIM applications source code, you won't see any runtime
checks for this. Instead, during development time, we look at the heap
after the form is loaded to make sure there's a good amount of room left.
>1) Ensuring that my code is always leaving sufficient headroom for "non
>optional requests", that unspecific number you refer to
Use this method.
>How many extra K is "a few"? ;-)
Somewhere around one to two. Much less than one is where things behave
oddly.
>I can't find the error to which you refer. Was this post 3.1 and that's
why I can't find it?
Most changes to Palm OS last year were added to 3.2 (Palm VII).
>I'm going to post to a different thread some questions regarding the
>console and how to use it.
Good. Go for it. I'm sure lot's of folks are interested while lot's of
others can help.
>I'm intuiting from Roger's suggestion in an earlier post that the dynamic
>heap can't be crowded out by the storage heap
They are indeed separate. The console commands can clearly show this.
>What's never been clear, (I can hear the seasoned pros sighing already),
is
>when one must explicitly allocate memory and when an implicit allocation
is
>fine.
OK.
If you need a bit of memory for a short bit of time, put it on the stack
(local variable). The benefits are the memory is cheap to allocate and
destroy. Don't do this for memory that 1) stays around a long time, 2) is
large, or 3) will be resized. Note that large varies. You can use a lot
more space in a function that never calls anything than one that allways
exists like PilotMain, because the later choice affects all other calls
from PilotMain.
If you need memory for the entire app and you need to read and write from a
variety of places, use your app's global memory. The benefits are the
memory is cheap to allocate and destroy. The drawbacks are 1) this doesn't
work other other launch commands and 2) it reduces the memory available for
the rest of the program. Obviously the amount of memory must be known at
compile time.
You'll need to use dynamically allocated memory for all the other requests.
The decision for pointer based chunks versus handle based isn't too hard to
make. Use handles if the memory is going to be resized. Use handles if
the memory is going to be allocated or destroyed at unpredictable times.
Use pointers for memory that is going to be allocated in an orderly manner,
like a function that allocates a bunch in a row and frees all before
exiting, or a bunch of allocates at the beginning of an app. The idea here
is that the pointer based memory should be allocated and freed in order.
Doing otherwise leaves holes which slows down the memory manager from
finding unused memory. Handles based memory should be left unlocked so
that it can compact and rearrange memory. Pointer and handle based memory
come from the same dynamic heap. Pointer based memory descends from the
top and handle based goes the other direction. They meet when the heap
fills up. Pointer based memory is a tiny bit faster than handle based.
If you have data that needs to be stored or is read only, keep it in the
storage heap.
Generally people who have lot's of memory questions haven't used the
console commands to inspect the memory heaps. I posted a dump of the
dynamic heap and it should be in the archives. I'll again post another
one. This is the Address Book after starting. Notice how little memory
the app takes up. Most of the data is kept in the database and app
resources.
Enjoy!
-Roger Flores
hd 0
Displaying Heap ID: 0000, mapped to 000015A2, first free: 00002188
req act
resType/ #resID/
start handle localID size size lck own flags type index attr
ctg uniqueID name
---------------------------------------------------------------------------
-----------------
-000018DA 000015B2 000015B3 000022 00002A #0 #0 fM Alarm Table
-00001904 000015B6 000015B7 000112 00011A #0 #0 fM
-00001A1E 000015BA 000015BB 000456 00045E #0 #0 fM Graffiti Private
*00001E7C 000015BE 000015BF 000304 00030C #1 #2 fM Form "Address
List"
00002188 -------- 00002188 010FCE 010FD6 #0 #0 FM --> 000132AE
?0001315E -------- 0001315E 000148 000150 #15 #0 fm
000132AE -------- 000132AE 000170 000178 #0 #0 FM --> 00018004
?00013426 -------- 00013426 000024 00002C #15 #0 fm DmOpenInfoPtr:
'AddressDB'
?00013452 -------- 00013452 001000 001008 #15 #0 fm
?0001445A -------- 0001445A 000088 000090 #15 #0 fm Handle Table:
'Address Book'
?000144EA -------- 000144EA 00003C 000044 #15 #0 fm
?0001452E -------- 0001452E 000038 000040 #15 #0 fm App Globals: UI
Shell
?0001456E -------- 0001456E 000600 000608 #15 #0 fm Stack: UI Shell
?00014B76 -------- 00014B76 00000E 000018 #15 #0 fm DmOpenRef:
'AddressDB'
?00014B8E -------- 00014B8E 00003C 000044 #15 #0 fm SysAppInfoPtr: UI
Shell
?00014BD2 -------- 00014BD2 000028 000030 #15 #0 fm UI: Window
(160x160)
?00014C02 -------- 00014C02 000064 00006C #15 #0 fm UI: Undo buffer
?00014C6E -------- 00014C6E 000118 000120 #15 #0 fm UI: Event Queue
?00014D8E -------- 00014D8E 000024 00002C #15 #0 fm DmOpenInfoPtr:
'Address Book'
?00014DBA -------- 00014DBA 000020 00002C #15 #0 fm UI: SysFontTable
?00014DE6 -------- 00014DE6 000018 000020 #15 #0 fm Sound Manager
Globals (SndGlobalsType)
?00014E06 -------- 00014E06 00006C 000074 #15 #0 fm Graffiti Glue
Globals (GrfGlobalsType)
?00014E7A -------- 00014E7A 000040 000048 #15 #0 fm Keyboard Queue
(KeyQueueType)
?00014EC2 -------- 00014EC2 000100 000108 #15 #0 fm Pen Queue
(PenQueueType)
?00014FCA -------- 00014FCA 000028 000030 #15 #0 fm System Event
Manager Globals (SysEvtMgrGlobalsType)
?00014FFA -------- 00014FFA 001900 001908 #15 #0 fm Screen Buffer
?00016902 -------- 00016902 00002E 000036 #15 #0 fm Source Blit Buffer
?00016938 -------- 00016938 00002E 000036 #15 #0 fm Screen Driver
Globals (ScrGlobalsType)
?0001696E -------- 0001696E 00002C 000034 #15 #0 fm Pen Manager Globals
(PenGlobalsType)
?000169A2 -------- 000169A2 000024 00002C #15 #0 fm Key Manager Globals
(KeyGlobalsType)
?000169CE -------- 000169CE 0000C0 0000C8 #15 #0 fm System Library
Table
?00016A96 -------- 00016A96 000010 000018 #15 #0 fm Alarm Manager
Globals (AlmGlobalsType)
?00016AAE -------- 00016AAE 000018 000020 #15 #0 fm Time Manager
Globals (TimGlobalsType)
?00016ACE -------- 00016ACE 0010A0 0010A8 #15 #0 fm Kernel Globals
?00017B76 -------- 00017B76 000010 000018 #15 #0 fm UI: AppFontTable
?00017B8E -------- 00017B8E 00000E 000016 #15 #0 fm DmOpenRef: 'Address
Book'
?00017BA4 -------- 00017BA4 000024 00002C #15 #0 fm DmOpenInfoPtr:
'Graffiti ShortCuts'
?00017BD0 -------- 00017BD0 00003C 000044 #15 #0 fm SysAppInfoPtr: AMX
?00017C14 -------- 00017C14 000040 000050 #15 #0 fm
?00017C64 -------- 00017C64 00000E 000016 #15 #0 fm DmOpenRef:
'Graffiti ShortCuts'
?00017C7A -------- 00017C7A 000094 00009C #15 #0 fm Battery Globals
(PrvBatteryGlobalsPtr)
?00017D16 -------- 00017D16 0002A4 0002AC #15 #0 fm Handle Table:
'System'
?00017FC2 -------- 00017FC2 000024 00002C #15 #0 fm DmOpenInfoPtr:
'System'
?00017FEE -------- 00017FEE 00000E 000016 #15 #0 fm DmOpenRef: 'System'
---------------------------------------------------------------------------
-----------------
Heap Summary:
flags: 4000
size: 016A5E
numHandles: #200
Free Chunks: #2 (01114E bytes)
Movable Chunks: #4 (0008AE bytes)
Non-Movable Chunks: #38 (004D2E bytes)
Owner 0: 01641E bytes
Owner 2: 00030C bytes