I am currently porting a game to the 3300, 6200, 6610 and 6800 phones. The game currently works on a number of Sanyo, Samsung and Motorola devices. The JAR size is 63714 bytes. The JAD file is 309 bytes.
The 3300 SDK User Guide specifies 63720 bytes as a 'magic' JAR size limit. We have (barely) succeded in acheiving that. As far as I am aware, the S40 phones have a 200K heap size, as do the Samsung phones on which the game runs fine.
So, for the problem:
In the 7210 emulator, the app crashes out as it begins to load with a Java OutOfMemoryException. Similar situation on the device (6610) without the helpful exception message. In the S60b3 emulator with JAR size limits set to 63720 and heap size capped at 200K, it works fine. Perhaps the S60 emulator doesn't really apply those limits, but that wouldn't explain why this app works fine on similar spec Samsung phones, and runs out of memory on the 7210.
Is there a similar 'magic' number to heap size? Does 200K really mean 'somewhere around 195K'?
Wow! I've never managed to find such a precise figure! The usual quote for S40 JARs is "64k". I have installed JARs larger than 63720 on my 6100, so I think the limit is not identical for each model. And I would guess the same applied to heap size... so 200k is a rough figure.
(Incidentally, I have installed a JAR of 65536 bytes (64k) by IR, but the same will not install OTA...)
I think there is a lot of sense in running the 7210 emulator with a reduced heap size (the documentation tells you how), to give yourself a margin of error.
It is probably not valid to assume that if your application works on one phone with a 200k heap, that it will work on others with a heap of the same size. For example, when Nokia phones load an image from the JAR, it is expanded into a native format. Other manufacturers' phones probably do the same, but will not all use the same format, especially where the devices have different display characteristics. There will be similar differences in the sizes of other implementation-specific objects.
The closer to the limits you are working, the more important it becomes to test on a variety of devices.
Re: the 63720 number. The 3300 SDK guide mentions that the emulator ensures the MIDlet-Jar-Size attribute in the JAD is equal or lower than that value, or it won't run it. Haven't tested it out on the actual hardware, but I wish those kind of specifics were more readily available.
You're right about the heaps not being equal. They're waaaay off. Did some tests by throwing some print codes into our main resource load loop. After loading 67% it crashes out with only 3K available memory. And that's with a System.gc() on each loop iteration (one per resource loaded).
Looks like I'll be having fun streamlining our resource manager for this one.
Just outta curiosity, in case anyone knows the details. Does the VM load the entire JAR into memory, or just the classes/data as required? If it loads the whole thing then all my resource data is already in memory and 'loading' it would be a waste. I wouldn't imagine they'd do this for such an already limited platform, but...?
Does the VM load the entire JAR into memory, or just the classes/data as required?
At least classes are not loaded on this basis.
From the very start phone loads your main class and all the classes it refers to (including imported classes) and all the classes they refer to and so on.
However if you include into JAR some class you don't refer to it is not loaded at the start of the app. You can load it later using Class.forName()