| C H A P T E R 3 |
|
Managing Native Resources |
The typical device is constrained in the amount of resources, such as memory or sockets, that it has available. When the Java Wireless Client software is running on a device, it is often provided with a fixed set of resources that it cannot exceed. In a single-tasking environment, a single MIDlet has access to all of the available resources. However, in a multitasking environment, multiple MIDlets might have to compete among themselves for this fixed set of resources.
For example, assume that the Java Wireless Client software has 600 kilobytes of heap memory, and that MIDlet A requires 400 kilobytes and MIDlet B requires 300 kilobytes. The user can run either MIDlet A alone or MIDlet B alone, and each works fine. However, if MIDlet A is running and the user starts MIDlet B, MIDlet B might receive an out-of-memory error.
MIDlets sometimes allocate only some of the memory they need at startup, but allocate more memory when a certain operation is performed. For example, suppose MIDlet A is running and consumes 350 kilobytes, and the user starts MIDlet B. At startup, MIDlet B might consume only 100 kilobytes and might appear to work fine. However, when the user attempts a particular operation using MIDlet B, it might allocate the additional 200 kilobytes, causing an out-of-memory error during its operation. Alternatively, if the user switches to MIDlet A and MIDlet A allocates more memory, then MIDlet A might receive the out-of-memory error.
This is a difficult problem because each MIDlet might test successfully with the Java Wireless Client software and work fine when run individually. However, when run at the same time, the MIDlets could appear to be unstable, receiving out-of-memory errors at unpredictable times.
The Java Wireless Client software solves this problem by providing a set of resource management mechanisms that can be used to control how resources are allocated. The Java Wireless Client software also provides a set of resource management policies that determine how the system behaves under certain conditions. These policies can be customized to tailor the behavior of the system for a particular deployment. Two example policies are also provided as a starting point for customization. Finally, the implementation of resource mechanisms and policies resides with the resource manager.
Java Wireless Client software has three resource management mechanisms: reservation, limit, and revocation.
The reservation mechanism sets aside a certain amount of a resource for a MIDlet and keeps it available for that MIDlet and that MIDlet alone, regardless of whether the MIDlet is using it at the moment. The reserved resource is never granted to another MIDlet. If another MIDlet attempts to allocate the resource, it might fail, even if the first MIDlet is not using all of its reservation.
Assume the heap memory available is 600 kilobytes, MIDlet A has a reservation of 400 kilobytes, but is currently using 250 kilobytes. 350 kilobytes of heap is unused. However, only 200 kilobytes is actually available, because 150 kilobytes of the unused heap is still reserved for MIDlet A. If MIDlet B starts and attempts to allocate 300 kilobytes of heap, it receives an out-of-memory error.
The reservation mechanism improves predictability and helps to prevent data corruption.
MIDlets allocate and free resources (particularly memory) throughout their operation. During a resource shortage, any allocation attempt might fail. These failures might occur at an arbitrary time, even in the midst of an operation. If MIDlet is provided with a reservation and is designed never to exceed this reservation, then its allocation attempts will never fail. Instead, the resources for the reservation are allocated at the time the MIDlet is started.
If there is a resource shortage, the failure will occur at startup time. Once the MIDlet has been started, it is guaranteed not to fail because of a resource shortage. This improves predictability because resource allocation failure occur only at startup time, not at arbitrary times while the MIDlet is running.
Many MIDlets are not designed to deal with failure in the midst of an operation. If such a MIDlet is updating one of its date structures when an allocation failure occurs, the date structure might end up in an inconsistent or corrupted state. Providing MIDlets with a resource reservation will prevent failures from occurring at arbitrary times, thus reducing the possibility of data structure corruption.
The limit mechanism allows a MIDlet to allocate up to a certain amount of some resource, but no more. If the MIDlet attempts to allocate more resources than its limit, the attempt fails, even if resources are actually available on the system. Conversely, fewer actual resources might be available than a MIDlet's limit might indicate. A MIDlet might attempt to allocate resources beneath its limit, but the attempt still fails if insufficient actual resources are available on the system.
For example, assume that 600 kilobytes total heap is available and that MIDlet A is using 400 kilobytes. MIDlet B has a limit of 300 kilobytes of heap. It receives an out-of-memory error after allocating 200 kilobytes, because that's all the heap available, even though it is under its limit. Suppose, however, that MIDlet B has a limit of 150 kilobytes. It receives an error after allocating 150 kilobytes, even though 50 kilobytes of heap is still available.
The limit mechanism is useful to prevent MIDlets from attempting to use all available resources and thereby disrupting the operation of the system.
Reservations and limits work in concert to control competition among MIDlets that are using a pool of resources, such as heap memory or network sockets. It is typical for a running MIDlet to have both a reservation and a limit in effect at the same time. Note that it only makes sense for the limit to be greater than or equal to the reservation. A limit differs from a reservation in that a reservation guarantees that the reserved amount of the resource is always available, but it doesn't prevent the MIDlet from attempting to exceed the reservation amount. A limit is quite complementary: It prevents the MIDlet from using more than a some amount of a resource, but it doesn't guarantee that the amount is available.
When resources are explicitly released by a MIDlet, they might or might not become available to other MIDlets. It depends on the reservation policy for the resources.
The revocation mechanism lets the system take a resource from one MIDlet to give the resource to another MIDlet. This second MIDlet is sometimes said to have preempted the resource from the first MIDlet. Resources are revoked without receiving any request from the MIDlet. The MIDlet might or might not be informed explicitly that the revocation is taking place, depending upon the type of resource being revoked.
After allocation by a MIDlet, many resources are deallocated explicitly by the MIDlet. For example, opening a socket allocates it, and closing the socket deallocates it, after which it can be reused by another MIDlet. If a socket is revoked, the underlying native resources are reclaimed, but the Java Socket object still exists. In this case, any subsequent operations on this Socket object results in an I/O error. The Java Wireless Client software doesn't revoke sockets.
Revocation is not always so drastic. Sometimes it can occur almost transparently to the application. The device's screen is a resource. When a MIDlet is put into the background, its access to the screen is revoked so that another MIDlet can paint to the screen. In this case, the only effect on the MIDlet might be that its hideNotify() method is called and that it no longer receives calls to the paint() method.
Another resource that can be revoked transparently is the CPU. When the CPU is revoked from a MIDlet, its threads simply stop running. When the MIDlet regains the CPU, its threads pick up where they left off.
The Java Wireless Client software provides two preconfigured resource allocation policies: open and fixed. The open policy allows open competition among applications for resources. The fixed policy provides a fixed amount of resources for each application. Under the fixed policy, the reservation and limit for each resource are set to the same value. Setting the reservation and limit to the same value effectively creates a fixed partitioning of resources.
The policies have tradeoffs. Neither is clearly better than the other. Using the open resource policy might lead to unpredictable behavior. An application could at any time receive an error that a resource is not available. Users might find this behavior confusing. Under the fixed policy, if the amount of available resources is less than the reservation amount for a new MIDlet, the system refuses to start any more MIDlets. This occurs even if the actual amount of unused resources is sufficient for the new MIDlet, meaning valuable resources might go unused. However, this behavior might be less confusing to the user than the failures that could happen with the open resource policy, because these failures are predictable. They always happen when the user tries to start the application.
The default policy is open for competition. To use a fixed-partition resource policy, you must set a build-time flag USE_FIXED=true. See the Sun Java Wireless Client Build Guide for more information.
Most implementations need to tailor resource allocation policies to each resource instead of specifying a blanket open or fixed policy for all resources. For example, on a particular platform, heap memory might be relatively plentiful, and so choosing a fixed policy for memory might be appropriate to gain predictability, possibly at the expense of some waste. However, another resource, such as network sockets, might be too scarce to tolerate any waste, even at the cost of some unpredictability. An open policy is more appropriate for these resources.
It is also possible to customize the reservations and limits to be somewhere between the extremes specified by the fixed and open policies. For example, a particular implementation might want to guarantee 250 kilobytes of heap memory for each MIDlet, but it doesn't necessarily want to constrain a large MIDlet from consuming as much heap memory as it wants. In this case, specify a reservation of 250 kilobytes and specify no limit on heap memory.
The resource allocation policies are specified in XML files in the following directories in the source tree:
src/configuration/configuration_xml/platform
These directories contain several XML files that specify various constants used in for all aspects of the system. For more information about these files and how to modify constants, see the Managing Properties and Constants chapter of the Porting Guide. The two XML files that specify the resource policies are constants_fixed.xml and constants_open.xml. The constants_fixed.xml file is used if the build flag USE_FIXED=true, otherwise the constants_open.xml file is used.
The best way to modify the resource allocation policy is to ensure that USE_FIXED=false (which is the default) and to modify the constants_open.xml file. Some of the constants in this file are described in TABLE 3-1. To specify no reservation or limit, use the value -1. For example, the default value of SUITE_MEMORY_LIMIT is -1, which sets no limit on the amount of memory that a MIDlet suite can allocate.
Each resource typically has five constants that define the policy. A pair of constants defines the reservation and the limit for each MIDlet suite. These constants have the suffixes SUITE_RESERVED and SUITE_LIMIT, respectively. Another pair of constants defines the reservation and limit for the AMS task. These constants have the suffixes AMS_RESERVED and AMS_LIMIT. Finally, the fifth constant specifies the global limit for the entire system. The sum of all allocations by all MIDlet suites and the AMS cannot exceed this limit. This constant has the suffix GLOBAL_LIMIT.
For certain resources, it is important to choose the AMS reservation carefully. For example, the AMS needs to open various MIDlet files in order to change application settings. If the AMS open file reservation is not set high enough, and running MIDlets have consumed all available file handles, the normal operation of the AMS will be disrupted.
Five constants determine the policy for TCP client sockets: the global limit, the reservation and limit for the AMS, and the reservation and limit for each MIDlet suite. This pattern of five constants is repeated for several different resources, including the following:
For each of these resource types, you can specify independently the global limit and the reservations and limits for the AMS and for each MIDlet suite.
Copyright © 2007, Sun Microsystems, Inc. All rights reserved. SUN PROPRIETARY/CONFIDENTIAL.