Login  Register

Re: TextRenderer memory leak?

Posted by farrellf on Aug 20, 2019; 10:19am
URL: https://forum.jogamp.org/TextRenderer-memory-leak-tp4039967p4039971.html

"Legacy"? Is there a newer way to do it?

I wrote a minimalist demo. To make the leak quick, I have 1000 TextRenderers. Here's what it looks like after 10 minutes. Toward the end I replace the TextRenderer objects with new ones, confirming that the old ones were getting very big.

https://imgur.com/a/3SCmPmr

Source code:

import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.awt.TextRenderer;

import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Date;

import javax.swing.JFrame;

public class MainMemoryLeak {
       
        static TextRenderer tr[] = new TextRenderer[1000];
       
        public static void main(String[] args) {

                GLCanvas glcanvas = new GLCanvas(new GLCapabilities(GLProfile.get(GLProfile.GL2)));
                glcanvas.addGLEventListener(new GLEventListener() {
                       
                        int width = 0;
                        int height = 0;
                       
                        @Override public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
                               
                                width = w;
                                height = h;
                               
                                GL2 gl = drawable.getGL().getGL2();
                               
                                gl.glMatrixMode(GL2.GL_PROJECTION);
                                gl.glLoadIdentity();
                                gl.glOrtho(0, width, 0, height, -1, 1);
                               
                                gl.glMatrixMode(GL2.GL_MODELVIEW);
                                gl.glLoadIdentity();
                               
                        }
                       
                        @Override public void init(GLAutoDrawable drawable) {

                                for(int i = 0; i < 1000; i++)
                                        tr[i] = new TextRenderer(glcanvas.getFont(), true, true);
                               
                        }
                       
                        @Override public void dispose(GLAutoDrawable drawable) {
                               
                        }
                       
                        @Override public void display(GLAutoDrawable drawable) {
                                       
                                GL2 gl = drawable.getGL().getGL2();
                               
                                gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);

                                for(int i = 0; i < 1000; i++) {
                                        tr[i].beginRendering(width, height);
                                        tr[i].setColor(Color.WHITE);
                                        tr[i].draw((new Date()).toString(), 10, 10 + i);
                                        tr[i].endRendering();
                                        tr[i].flush();
                                }
                               
                                gl.glFlush();
                               
                        }
                       
                });
               
                glcanvas.addKeyListener(new KeyListener() {
                       
                        @Override public void keyPressed(KeyEvent e) {
                                if(e.getKeyChar() == 'a') {
                                        System.out.println("Replacing the TextRenderers.");
                                        for(int i = 0; i < 1000; i++)
                                                tr[i] = new TextRenderer(glcanvas.getFont(), true, true);
                                }
                        }
                       
                        @Override public void keyTyped(KeyEvent e) { }
                        @Override public void keyReleased(KeyEvent e) { }
                       
                });
               
                JFrame frame = new JFrame("Memory Leak Demo, After several minutes: click in the window, then press 'a' to see the leak disappear.");
                frame.add(glcanvas);
                frame.setSize(700, 400);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
       
                Animator anim = new Animator(glcanvas);
                anim.start();
               
        }
       
}
Is there a better way to do text? If not, is there a way to query the size of a TextRenderer so I can replace it when it gets a certain size? If not, is the best workaround to just replace each TextRenderer every n frames?

-Farrell