0

I'm having some performance problems on a Swing based application I've been tasked with maintaining - I suspect a memory leak. After profiling, it appears that there is a very large amount of time being spent in the main application class (ie the entry point), specifically in a method that passes a reference to it's own Application object, like this:

  public synchronized static ProblemApplication getApplication() {
    if (s_Instance == null) {
      initializeInstance();
    }
    return (ProblemApplication ) s_Instance;
  }

  private synchronized static void initializeInstance() {
    s_Instance = Application.getInstance();
  }

This is called a lot throughout the code - a typical usage:

  private void updateSensorsModel() {
    ProblemApplication application = ProblemApplication .getApplication();

    int sensorIndex = 0;
    m_SensorModels.clear();

    // add sensors information
    for (SensorConfiguration s : application.getSensorsConfiguration().getSensors()) {
      m_SensorModels.add(new SensorModel(sensorIndex, application));
      sensorIndex++;
    }

    // add extra session information
    for (ExtraSession es : application.getSession().getExtraSessions()) {
      m_SensorModels.add(new SensorModel(-1, application, es.getDeviceID()));
    }
  }

and with some action listeners:

// listeners
final TechsasSession session = TechsasApplication.getApplication().getSession();
session.addPropertyChangeListener(new PropertyChangeListener() {

  @Override
  public void propertyChange(PropertyChangeEvent evt) {
    if (evt.getPropertyName().equals("sensorsConfiguration")) {
      SensorTableModel model = sensorTable.getModel();
      model.updateModel();
      repaint();
    }
  }
});

Anyway I've got very little Swing, and my Java (especially this kind of stuff) is a bit rusty.

Is this use of a synchronised singleton application object legitimate in this kind of environment?

I know that particular usages of it could be causing issues even if the approach is sound, I guess I just want to know if this is a likely candidate for my problems and something I should investigate further. The usage feels wrong to me - but that could just be me!

Thanks for your help.

Caligari
  • 1,381
  • 2
  • 10
  • 14
  • possible duplicate of [How to find a Java Memory Leak](http://stackoverflow.com/questions/40119/how-to-find-a-java-memory-leak) – DavidPostill Jul 18 '14 at 08:09
  • Thanks for the link. Similar issue (and I'll follow the suggested process), but IMO not exactly a duplicate. I guess a better title for the question would be something like 'Is accessing a synchronised Swing Application instance best practice?' But it'll be interesting to see what the linked process yields. – Caligari Jul 19 '14 at 09:03

1 Answers1

1

I think you might solve this by eliminating the synchronized nature of the method; to do that, just initialize the variable when the class is loaded. The obvious way to do this is with a static initializer, which you may need to look up -- it is a code block that is executed when the class is loaded, so it completes before any use of the class is made.

Synchronizing a method can take significant time in comparison to method calls without synchronization, so this is an easy thing to try. It doesn't have much to do with Swing, but it's a lot simpler to do something about in this case.

edit: --------------------

You don't say why you suspect a memory leak, or indeed what you mean by a "performance problem"; I think it is far more usual, in a Swing or other GUI application, to have a "performance problem" somewhere besides the synchronized call to a method, even if it's called often. But this is the code you identified, and the first thing I saw about it related to performance. I hope it helps, but it won't surprise me much if your problem is something you have not said and is caused by something you haven't mentioned. Just saying.

arcy
  • 12,845
  • 12
  • 58
  • 103
  • Sorry, should have clarified what I meant by performance problems - basically it'll start up and run fine for a few hours, but over time the memory size will steadily increase, and CPU usage likewise increases, until the whole application has hung at 100% CPU and most of the system's memory a few days later. – Caligari Jul 18 '14 at 02:08