[ http://issues.apache.org/jira/browse/HARMONY-38?page=all ]
     
Tim Ellison resolved HARMONY-38:
--------------------------------

    Resolution: Fixed

Paulex,

Fixed in NIO module at repo revision 372204
 - com.ibm.platform.struct.AbstractMemorySpy.java
 - com.ibm.platform.struct.RuntimeMemorySpy.java

Please check that this fully resolves the problem.


> com.ibm.platform.struct.AbstractMemorySpy doesn't actually autoFree native 
> memory
> ---------------------------------------------------------------------------------
>
>          Key: HARMONY-38
>          URL: http://issues.apache.org/jira/browse/HARMONY-38
>      Project: Harmony
>         Type: Bug
>   Components: Classlib
>     Reporter: Paulex Yang
>     Assignee: Tim Ellison
>     Priority: Critical
>  Attachments: Harmony38-AbstractMemorySpy-patch.txt, 
> Harmony38-RuntimeMemorySpy-patch.txt
>
> com.ibm.platform.struct.IMemorySpy is a memory watcher, and the 
> AbstractMemorySpy is a default implementation working with nio direct buffers 
> to free the native memories when direct buffer instances are garbage 
> collected. But currently its auto free donsn't work.  
> Look inside the orphanedMemory(Object obj) method, the memory is freed only 
> if the local variable wrapper can be found from the memoryInUse, a Map which 
> records the native memories used by direct buffers, but actually it will be 
> removed when autoFree(PlatfromAddress) is invoked. Checking the autoFree() 
> reference, I found that all DirectByteBuffer will invoke autoFree() in 
> constructor, which means no memory will be freed. 
> A simple fix:
> modify the Ln 94 in autoFree() from:
>         wrapper = (AddressWrapper) memoryInUse.remove(address);
> to:
>         wrapper = (AddressWrapper) memoryInUse.get(address);
> and it should work.
> The steps to reproduce the bug:
> 1. Add the following line in the the Ln109, which indicates the memory is 
> auto freed by AbstractMemorySpy
>          System.out.println("MemorySpy autofree:"+wrapper.shadow);
> 2. Run the test below:
> public class MemorySpyTest {
>     public static void main(String[] args) throws Exception {
>         for (int i = 0; i < 1000; i++) {
>             try{
>                 ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
>                 buffer = null;
>             }catch(Exception e){
>                 e.printStackTrace();
>             }
>             System.gc();
>         }
>     }
> Before modification: application exits silently.
> After modification, hundres of lines printed out, like this:
> .....
> MemorySpy autofree:PlatformAddress[9310024]
> MemorySpy autofree:PlatformAddress[9311056]
> MemorySpy autofree:PlatformAddress[9312088]
> MemorySpy autofree:PlatformAddress[9313120]
> MemorySpy autofree:PlatformAddress[9314152]
> MemorySpy autofree:PlatformAddress[9315184]
> MemorySpy autofree:PlatformAddress[9316216]
> MemorySpy autofree:PlatformAddress[9317248]
> .......
> Another possible pitfall in AbstractMemorySpy is it uses WeakReference and 
> ReferenceQueue to get notification when the buffers are ready to be garbage 
> collected. But it is not so safe yet to free the native memory, because the 
> weakly-reachable object has its chance to be resurrected to 
> strongly-reachable, if only some finalize() method doing this is executed. A 
> safer solution is to use PhantomReference instead, because phantom-reachable 
> object has no chance to survive. The only concern is the PhantomReference 
> should be explicitly cleared by application, but that's OK because the 
> orphanedMemory() method is a perfect candidate to do this. 
> I will attach the patch soon.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira

Reply via email to