PDA

View Full Version : hme 1.4 memory leak or user error?


toups
11-04-2009, 11:52 PM
I am playing around with creating an app and am fairly new to Java. Here are two code snippets.


BufferedImage myScreenImage=myCaptureRobot.createScreenCapture(screenRecta ngle);
ImageIO.write(myScreenImage,"PNG",new File("testf.png"));
bg.setResource(createImage("testf.png"));

and


BufferedImage myScreenImage=myCaptureRobot.createScreenCapture(screenRecta ngle);
bg.setResource(myScreenImage);

Note bg is defined by:
bg = new View(root, 0, 0, root.getWidth(), root.getHeight());

The difference is in one case I am using bg.setResource with a PNG image file the other with a image object. Both pieces of code give the proper results on the TiVo screen. However, on the application server, the heap grows as this block of code is executed multiple times until I run out of memory. The first version, the heap is stable and has no problem.

Is there a memory leak in setResource with an image object? Or have I missed some fundamental concept and need to free something up after executing the block?

davidblackledge
11-05-2009, 11:12 AM
I don't have the SDK source in front of me, but I can tell you what I recall.

Creating an Image Resource from an Image object keeps a reference to the Image object in the Resource... and the resource reference sticks around until it is explicitly removed... it's not enough to replace the resource in the view because in theory you might be using that same resource in another view or something. Instead, for that case, call bg.getResource().remove() to free up that memory if you don't need it anymore... if you do need it, then keep a reference to it and re-use it instead of creating new ones.

All the SDK needs to keep of the Image object is its width/height and the id it gets back from the TiVo...but it doesn't do that ,unfortunately. I tried a couple of things to work around that before (a new ImageResource class that disposes of the image reference... works, but didn't work when I tried to run it under Galleon since it had to be sneaky and call itself part of the SDK's package... the other one was an Image class that disposed of the data after it had been requested once, but the underlying ImageIO conversion classes the SDK uses only support a fixed list of class instances and reject anything else)
The createImage must be sending the image as a stream, rather than as an object.... OR it's modifying a single image resource object (keyed by the name of the file) and not creating new ones. I think it's creating a stream since it's using a file by name.

Anyhow... as you saw, using a file/stream is the best way to go... and in general if you can say getResource("string") it's the best thing to do since the SDK does the right thing and manages the cached resource IDs and reuses them if you use the same string. You can use that for images (local files or URLS), sounds, mp3s (local files or URLS), fonts, and animations...unfortunately you can't use it for text resources, though.

More detail at an older post: http://www.tivocommunity.com/tivo-vb/showthread.php?p=6701148#post6701148

toups
11-05-2009, 10:39 PM
Thanks, that explains a lot.

I'll have to investigate more later.

toups
11-07-2009, 10:44 AM
Thanks for the help.

For now, I am using the following code:

BufferedImage myScreenImage=myCaptureRobot.createScreenCapture(screenRecta ngle);
ByteArrayOutputStream imageByteArray = new ByteArrayOutputStream();
ImageIO.write(myScreenImage,"png",imageByteArray);
bg.setResource(createImage(imageByteArray.toByteArray()));



I am working on an app that allows me to run Xvfb on my linux server and display the X window on the linux box and control the mouse, etc. with the TiVo remote. Next step is to only update if the screen actually changed. I guess I will need to compare the recent capture to the old capture unless there is some way to get X to generate an event after an update that triggers the capture.

wmcbrine
11-07-2009, 03:11 PM
I am working on an app that allows me to run Xvfb on my linux server and display the X window on the linux box and control the mouse, etc. with the TiVo remote.Have you seen this?

http://www.duckcreeksoftware.com/public/remotecontrol/

toups
11-07-2009, 09:55 PM
Have you seen this?

http://www.duckcreeksoftware.com/public/remotecontrol/

No, but it appears the functionality is effectively very similar to what my code is starting to do. In my case the goal is to have a remote linux X window running that is not the main window on the host machine. (However, if I didn't use the X virtual frame buffer, mine would control the main window.) The initial goal was to be able to run a full featured browser to browse quasi-static pages initially. However, I realized that to do what I wanted was easiest using a virtual X setup with Xvfb and a light weight window manager. Hence, I wasn't limited to running a browser but anything.

However, my real goal is to get some practice with Java.

P.S. Today I added code to only reload the screen if it changes. I found that I had to do a simple trick to avoid trying to refresh a screen just to display a blinking cursor. This helped my ability to move a cursor smoothly around the screen.