TOPIC There are two common types of memory leaks in WebObjects Java applications: leaks caused by the Java garbage collection scheme and leaks due to known problems with Java or the WebObjects Java components. This article discusses ways to prevent and analyze both types of memory leaks. This article assumes that you are using WebObjects 4. DISCUSSION Leaks due to garbage collection Often, the garbage collector has to run many times in order to completely find and free every unused object. The Sun garbage collector is not very aggressive; It often stops collecting even when there is more garbage left. Object references across the Java bridge can require many passes of the collector before they are cleaned up. Since the Java garbage collector cannot see references made by Objective C objects, they will appear as global, or non-collectable, references. Thus, several collections may be required to resolve some relationships; the Java garbage collector, then the Objective C garbage collector, then the Java garbage collector again, and so on. This results in memory temporarily leaking from the application. For example, when Objective-C objects have their Java side garbage collected by the Java Garbage Collector thread, they themselves are not immediately dealloc'd. This happens only when the main thread crosses the Java bridge. When the Bridge frees up the global retain count it keeps on behalf of the Java VM for the Objective-C object, it may free up more Java/Objective-C objects. In order to reach a steady state over time, you will need to cause multiple runs of the garbage collector by forcing a loop of collection and autorelease. You can do this in WebObjects 4 by setting two different environment variables which tell the garbage collector to loop collection during session deallocation, WOGarbageCollectionRepeatCount and WOWorkerThreadCount. WOGarbageCollectionRepeatCount is used to force garbage collection to occur a sufficient number of times so that most of the objects held by timed out sessions will be freed. A value of 3 for WOGarbageCollectionRepeatCount means that WebObjects assumes that you have object graphs that are (on average) about three references deep. This is also the default value in case no user default is specified. WOGarbageCollectionRepeatCount == 0 means that the garbage collector isn't run upon session deallocation. WOWorkerThreadCount specifies the maximum number of worker threads for a multithreaded application. The default value for WOWorkerThreadCount is 8. Setting this count to 0 results in a single threaded request dispatch, similar to WebObjects 3.5.1. Please note that if WOWorkerThreadCount value == 0, then WOGarbageCollectionRepeatCount will no longer have any effect. In Project Builder, bring up the Launch Panel and add the following launch arguments: -WOWorkerThreadCount 8 -WOGarbageCollectionRepeatCount 6 WOWorkerThreadCount can have any value greater than zero, and WOGarbageCollectionRepeatCount can have any value between 3 and 8. You can also specify these two variables when starting your application from the command line. Please note that running the Garbage Collector repeatedly may affect the performance of your application. Leaks due to known Java memory problems Static or global references Leaks can occur if your application keeps an array of allocated sessions, or some kind of global notification registry. Since Java (in JDK 1.1) does not support weak references, any object placed in that array, and all objects referenced by that array, will never be collected. Even in JDK 1.2, using weak references correctly to avoid this problem is still problematic. Retain cycles across the Java bridge One potential source of leaks is when your application creates a reference cycle across the bridge. For example, WOApplication has an Objective C retain on its WOSessions. If a Java subclass of WOSession then adds an instance variable to point at WOApp, you have created a cycle across the bridge and your session will never be collected. This problem is documented in the WebObjects 4 release notes as follows: Apple Reference # 2282368 Problem: Java Inner classes can create retain cycles resulting in leaked sessions and pages. Description: If you are using inner classes in your session and/or pages, be aware that non-static inner classes have a hidden pointer to their owning class. This make it easy to get into situation where a mixed objC-Java retain cycle is created, preventing the deallocation of all objects on that cycle. For example, if you pass an instance of an inner class of a page to one of its subcomponents, you get the following cycle:
yourSubcomponent > theInnerClassInstance > (through the hidden ivar) theTopLevelPage > (through normal objC containment) > yourSubComponent
|
Document Information | |
Product Area: | WebObjects |
Category: | WebObjects 4 |
Sub Category: | Development |
Copyright © 2000 Apple Computer, Inc. All rights reserved.