Please tell me how to cope with a memory leak or more to solve the problem.

Once a second, I get the values ​​from the database that need to be processed. The resulting data array is processed in separate threads so as not to slow down the process:

public class MyThread extends Thread{ @Override public void run(){ Map<Integer, MyObject> ar = new HashMap(); while(true){ //запрос к базе while(resultSet.next()){ ar.put(resultSet.getInt(1),new MyObject()); } if(!ar.isEmpty(){ WeakReference<MyHandler> ex = new WeakReference<MyHandler>(new MyHandler(ar)); ex.get().start(); ar.clear(); } //затем обновляю строки в базе по массиву, что бы сделать следующую выборку } }} public class MyHandler extends Thread{ Map<Integer, MyObject> ar; public MyHandler(Map<Integer, MyObject> ar){ this.ar = new HashMap<>(ar); } @Override public void run(){ //обработка массива }} 

So I have a memory leak, how can I implement it differently? A lot of threads are created, I don’t know how they release memory at the end.

Thank you in advance!

  • You in vain manually create threads, there is a ThreadPoolExecutor to take a thread exactly at the time when it is needed. - etki
  • And why do you think there is a leak? In general, each Thread is gc-root, i.e. as long as the stream is alive, objects referenced in the stack cannot be collected. But if MyHandler completed, then the map with all its contents should be collected. WeakReference for a local variable, in my opinion, is not needed. - zRrr
  • @zRrr in this case, the leak is not because of this? - WuDengin
  • I dont know. If the program crashes with OutOfMemoryError , run jvm with the -XX:+HeapDumpOnOutOfMemoryError key -XX:+HeapDumpOnOutOfMemoryError , and analyze the resulting heap dump in Eclipse MAT or its counterparts, there you will see which objects are in memory. You can also connect jvisualvm (included in jdk) to the running program and see - zRrr
  • Try testing the application using the VisualVM utility. - Ksenia

1 answer 1

Offhand why

 Map<Integer, MyObject> ar = new HashMap(); 

created out of loop?

You transfer it to all handlers, it is unclear if it is cleared at all, or it contains all the data accumulating it.

That's how it should be

 while(true){ //запрос к базе Map<Integer, MyObject> ar = new HashMap(); while(resultSet.next()){ ar.put(resultSet.getInt(1),new MyObject()); } if(!ar.isEmpty(){ WeakReference<MyHandler> ex = new WeakReference<MyHandler>(new MyHandler(ar)); ex.get().start(); } // здесь обрабатывать пока нечего, потому что данные будут готовы асинхронно в MyHandler // если все-таки данные нужны здесь, то нужно обрабатывать их синхронно, выкинув MyHandler вообще } 
  • forgot to add a record, clear it up after it passed to the stream - WuDengin
  • В Java объекты всегда передаются по ссылке, а примитивы - по значению - know about it? All your handlers will have an empty data set. Because you have one at all and you clean it immediately after filling. - Eugene Krivenja
  • Well, primitives are not by value, but by cached link. - Denis Kotlyarov
  • @EugeneKrivenja So I have the curve code, but it’s generally necessary to make a request for certain data from the database every second, if there is, then process them without slowing down the speed of requests to the database every second ... can you tell me how to do it elegantly?) Map I'm in Handler the one that was passed to the constructor this.ar = new HashMap <> (ar); - WuDengin
  • one
    If the processing does not keep up with the receipt of data, the application in any case, sooner or later OutOfMemoty in OutOfMemoty . Then what is the point of every second samples? Choose when ready to process. - Eugene Krivenja