Chuidiang en mi caso solamente uso una única ventana para el tema de las gráficas y otra para la visualización de la figura en 3D. El error que me salta es el siguiente:
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
at java.awt.image.DataBufferInt.<init>(DataBufferInt.java:41)
at java.awt.image.Raster.createPackedRaster(Raster.java:458)
at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1015)
at java.awt.image.BufferedImage.<init>(BufferedImage.java:312)
at org.jfree.chart.JFreeChart.createBufferedImage(JFreeChart.java:1384)
at org.jfree.chart.JFreeChart.createBufferedImage(JFreeChart.java:1366)
Dentro de esa función a la que llamo varias veces, cada 100 msegundos por ejemplo, tengo el siguiente código:
public BufferedImage creaImagen(int datoMostrar, int tipoGraf, int colHex1, int colHex2)
{
double valorMax1 = 0, valorMax2 = 0, valorMin = 0;
if(datoMostrar == 0)
{
if(this.reiniciarSim == 1)
{
if(tipoGraf == 1)
{
serie1.clear();
serie2.clear();
}
else
{
serie3.clear();
serie4.clear();
}
}
//if(CajaX1.isSelected() == true)
//serie1.add(0, 0);
//if(CajaX2.isSelected() == true)
//serie2.add(0, 0);
}
else
{
i = i + 0.1;
if(CajaX1.isSelected() == true && tipoGraf == 1)
{
valorMax1 = variables.getRef();
//System.out.println("Aqui leemos " + valorMax1);
serie1.add(i, valorMax1);
}
if(CajaX2.isSelected() == true && tipoGraf == 1)
{
valorMax2 = variables.getVarContr();
serie2.add(i, valorMax2);
}
if(CajaX3.isSelected() == true && tipoGraf == 2)
{
valorMax1 = variables.getSeñalControl();
serie3.add(i, valorMax1);
}
}
juegoDatos.removeAllSeries();
if(CajaX1.isSelected() == true && tipoGraf == 1)
juegoDatos.addSeries(serie1);
if(CajaX2.isSelected() == true && tipoGraf == 1)
juegoDatos.addSeries(serie2);
if(CajaX3.isSelected() == true && tipoGraf == 2)
juegoDatos.addSeries(serie3);
/*if(i < 60 && this.time.equals("Min.") == false)
this.time = "Seg.";
else
{
if(this.limpiar == 1)
{
serie1.clear();
serie2.clear();
this.limpiar = 0;
}
this.time = "Min.";
i = 1;
}*
String tituloEjeX = new String();
tituloEjeX = "Tiempo (" + time + ")";*/
if(tipoGraf == 1)
{
chart = ChartFactory.createXYLineChart("Referencia y Variable Controlada", "Tiempo (Seg.)","Valor",juegoDatos,PlotOrientation.VERTICAL,true,
false, true);
chartAuxiliar = ChartFactory.createXYLineChart("Referencia y Variable Controlada", "Tiempo (Seg.)","Valor",juegoDatos,PlotOrientation.VERTICAL,true,
false, true);
}
else
{
chart = ChartFactory.createXYLineChart("Señal de Control", "Tiempo (Seg.)","Valor",juegoDatos,PlotOrientation.VERTICAL,true,
false, true);
chartAuxiliar2 = ChartFactory.createXYLineChart("Señal de Control", "Tiempo (Seg.)","Valor",juegoDatos,PlotOrientation.VERTICAL,true,
false, true);
}
plot = chart.getXYPlot();
rangeAxis = (NumberAxis) plot.getRangeAxis();
if(tipoGraf == 1)
{
valorMin = valorMax1;
if(valorMax1 > valorMax2)
valorMin = valorMax2;
if(valorMax1 == 0 && valorMax2 == 0)
rangeAxis.setRange(0, 10);
else if(valorMax1 < valorMax2)
rangeAxis.setRange(valorMin - 20, valorMax2 + 20);
else if(valorMax1 >= valorMax2)
rangeAxis.setRange(valorMin - 20, valorMax1 + 20);
}
else
rangeAxis.setRange(valorMax1 - 20, valorMax1 + 20);
domainAxis = (NumberAxis) plot.getDomainAxis();
if(i <= 10)
domainAxis.setRange(0, 10);
else if(i > 10)
domainAxis.setRange(i - 10, i);
xyplot = chart.getXYPlot();
xylineandshaperenderer = (XYLineAndShapeRenderer)xyplot.getRenderer();
Color color1 = new Color(colHex1);
xylineandshaperenderer.setSeriesPaint(0, color1);
Color color2 = new Color(colHex2);
xylineandshaperenderer.setSeriesPaint(1, color2);
image = chart.createBufferedImage(310,296);
return image;
}
Este método se llama por un temporizador, al que le fijo un tiempo entre llamadas según las necesidades del usuario. No sé donde puede estar el problema pero.... el error sigue saliendo. ¿Es posible que haciendo un Thread.sleep() pueda el recolector de basura eliminar de la memoria los elementos no necesarios?
El problema de dormir el hilo es que al tener un temporizador que se llama con una remanencia determinada, eso puede hacer quizás que no funcione adecuadamente y que el Thread.sleep() no sriva de nada, ¿o me equivoco? También he pensando en que cuando vea que la memoria se está acabando, aumentar el tiempo entre llamadas lo bastante como para que la memoria se vacíe lo necesario, ¿o eso no es posible?
Yo de Java entiendo pero no lo suficiente como para saber si eso que comento es correcto, ya que no sé cómo actúa el recolector de basura. Por esta razón os pido ayuda y consejo para poder sacar este tema adelante.
Espero poder solucionar esto hoy porque me es urgente y ¡¡¡¡el cliente quiere el laboratorio para ya!!!!
Un saludo y muchas gracias desde ya

.