cloister
Full Member
Offline
Posts: 138
Re: Rendering in Applet
Reply #1 - Feb 20th , 2009, 10:58pm
I am by no means an expert on how exported applets behave, but it sounds to me like your code does two things of relevance: a) draw at a high frame-rate, and b) use a lot of CPU. I can't tell whether it also ends up consuming a lot of temporary memory for each frame without seeing the code. All of that's fine when you're running in the dev environment because the environment can (and probably does) work on your behalf to help make sure that your code gets the CPU and memory resources it needs. But when you run in the browser, well, all bets are off. Browsers also have to do god knows how many other things all the time--responding to user events, listening on the network, et cetera. The browser is responsible for hosting your JVM, and almost certainly runs it with different parameters (available memory, CPU throttling, garbage cleanup frequency) than the dev environment. So I'm not at all surprised that a high frame rate applet might degrade a bit when running in the browser. The specific behavior you describe sounds to me like periodic invocation of the JVM's garbage collector, which is a sign that your application repeatedly allocates, uses, and then lets go of, chunks of memory. This is where I would start investigating. Try to avoid doing a lot of work in the draw() function, particularly creating objects with new, loading fonts, et cetera. The reason is that if you create those things as local variables within draw(), they'll go out of scope when draw exits. The next time Processing calls draw() for you, everything starts fresh. The memory associated with those local variables is gone, unavailable to you. Eventually, you'll have used up all the memory available to the JVM, at which point it will run the garbage collector to properly release all the stuff you lost track of. For example, this draw() leaks 1k of memory on each pass: void draw() { int[] foo = new int[256]; // ints are 4 bytes, so this is 1k for(int i = 0; i < 256; i++) // make a list of random numbers foo[i] = random(0, width); fill(255); stroke(0); for(int i = 0; i < 256; i++) line(foo[i], 0, foo[i], height); } Every time the code hits that "new int[256]", it says "hey, JVM, gimme another 1k!" When draw() exits, it's lost to the void. Eventually, the garbage collecter has to intervene to save you from yourself. This code keeps track of the array so you only ever allocate it once, and your code doesn't trigger the garbage collector: int[] foo = null; void draw() { if(foo == null) // the first time through draw(), allocate the array. Subsequent times, re-use it. int[] foo = new int[256]; // ints are 4 bytes, so this is 1k for(int i = 0; i < 256; i++) // make a list of random numbers foo[i] = random(0, width); fill(255); stroke(0); for(int i = 0; i < 256; i++) line(foo[i], 0, foo[i], height); }