Failure to release memory when releasing java objects

4 ビュー (過去 30 日間)
Sean
Sean 2011 年 9 月 30 日
(EDITTED... PLEASE SEE COMMENT FOR UPDATED QUESTION)
I have a couple of java .jars that I am using to control a camera and framegrabber in a test setup. They work correctly in that I can get the data I need, and when I release the relevant java objects (in matlab), the hardware become available for use by other code.
Unfortunately, the largest contiguous memory block available after release drops from ~1300MB before getting the main object instance to ~500MB after releasing the object. If I continue to connect and release, this decreases further (although by a much smaller margin).
Even if I clear all variables (or even explicitly 'clear all' or 'clear classes') the memory remains discontiguous. The only way I know to fix it is to quit/restart matlab, and that isn't a good option, because I want other processing to be automatically performed after data acquisition occurs.
Is there something I could be doing in matlab that would cause this, or is it something I need to take up with the developers of the .jar/.dll files?
Below is a segment of the method-code for the matlab object I am using:
%(Camera) function call
%This function is used to create the initial camera object and
%initialize all the connections needed to the CCU and framegrabber.
function obj = Camera(IPAddress) %IPAddress should be a string
import nca.io.*;
obj.camobj = CNCACamera(IPAddress);
if ~obj.camobj.isReady
error(strcat('Problem connecting to CCU @ ',IPAddress, ': Not Ready'))
end
import ksi.jace.AVIO.AVIO;
import ksi.jace.IAVIO.IAVIOBoard;
import ksi.jace.IAVIO.IAVIOBoardFactory;
import ksi.jace.IAVIO.IAVIOInputStream;
obj.AVIOAInstance = AVIO.getInstance();
obj.AVIOBBoard = obj.AVIOAInstance.getBoard(0,1);
obj.AVIOCStream = obj.AVIOBBoard.GetInputStream();
obj.AVIODSource = obj.AVIOCStream.GetInputStreamSources();
obj.AVIOCStream.SetInputStreamSource(obj.AVIODSource(3));
%Communicate with CCU and get type/SW/etc?
end
%(Release) function call
%This function releases the hardware for future use.
function Release(obj)
obj.AVIODSource(4).Release();
obj.AVIODSource(3).Release();
obj.AVIODSource(2).Release();
obj.AVIODSource(1).Release();
obj.AVIOCStream.Release();
obj.AVIOBBoard.Release();
obj.AVIOAInstance.destroyBoard(obj.AVIOBBoard);
obj.camobj.uninit;
clear obj
end
Thanks in advance for any/all help.
  1 件のコメント
Sean
Sean 2011 年 10 月 12 日
I have been able to determine that the cause of the memory not clearing is that the .dlls call other .dlls and do not clear them. The public release functions do not clear the lower level driver .dlls.
It seems that I may have to settle for trying to get the .dlls to load outside the largest contiguous memory block. I can do this manually by:
1) calling matlab 'memory' to determine largest block
2) preallocating an array to fill the block
3) initializing the objects
4) clearing the preallocated array
Unfortunately, I would like to do this in an automated fashion. Does anyone know of a way to a) force .dlls to load in the smallest block available and sufficient, or b) programatically determine the largest contiguous block and the maximum available memory?

サインインしてコメントする。

採用された回答

Sean
Sean 2011 年 10 月 17 日
After much investigating:
Some of the memory can not be freed up because it is allocated to external .dlls that don't bother to release it. Fortunately, this does not need to clutter my contiguous memory space.
I have resolved the problem of contiguous memory fragmentation by:
1) Reading the currently available memory stats, and 2) Preallocating a large contiguous block before creating the relevant java objects, and 3) Clearing the preallocated block after instantiation.
This forces the .dlls to use smaller available memory blocks.
Example code:
x=memory
x=ones(1024,1024,min(floor(x.MaxPossibleArrayBytes/(1024*1024*8)), ...
floor( x.MemAvailableAllArrays/(1024*1024*8)-60)));
Where the -60 is intended to ensure that all the .dll required memory is left available.

その他の回答 (1 件)

Malcolm Lidierth
Malcolm Lidierth 2011 年 10 月 2 日
clear obj in the Release function serves no useful purpose - it only clears the local copy of obj in the scope of that function.
"clear all" would clear the base and the function workspace - but not that of the function calling Release.
Try "clear all" at the command prompt once everything is closed.
If the jar is on the dynamic path,try "clear java" at the command prompt and look for warnings
  1 件のコメント
Sean
Sean 2011 年 10 月 7 日
Thanks for your response.
With respect to the three suggestions you made:
1) I have the 'clear obj' command in the code, because it was my impression that variables in function-space do not automatically clear when the function returns (resulting in fragmented memory). Perhaps I have misunderstood this behavior in matlab, but it has been my observation that unless I clear everything I can inside a function, I end up with lots of memory fragmentation.
2) If I use clear 'obj' or clear all at the command line, the variable disappears from the workspace, but not all the memory is released. Example: Before obj instantiation there will be ~1300MB of contiguous memory available. After obj instantiation, the larrgest contiguous memory block drops to ~500MB. If I release the object, the largest block increase to something like 515MB instead of returning to 1300MB (even though nothing was done but instantiation and immediate release).
3) The .jar is on the static path. For some reason, I could not get it to work on the dynamic path, and everything I've read suggests that using the static path is (generally speaking) better practice.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangePerformance and Memory についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by