Informix

Informix

Connect with Db2, Informix, Netezza, open source, and other data experts to gain value from your data, share insights, and solve problems.

 View Only
Expand all | Collapse all

Informix JDBC driver cleanup bug - memory leak

  • 1.  Informix JDBC driver cleanup bug - memory leak

    Posted Tue June 11, 2024 09:16 AM

    I have a problem when hot deploying our Java service to Tomcat, when the app is restarted getting the following WARNING:

    07-Jun-2024 14:18:12.815 WARNING [Catalina-utility-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [dashboard] appears to have started a thread named [IfxSqliConnectCleaner-Thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
     java.base/jdk.internal.misc.Unsafe.park(Native Method)
     java.base/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:269)
     java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1758)
     java.base/java.util.concurrent.DelayQueue.poll(DelayQueue.java:305)
     java.base/java.util.concurrent.DelayQueue.poll(DelayQueue.java:100)
     com.informix.jdbc.IfxSqliConnect$IfxSqliConnectCleaner.run(IfxSqliConnect.java:645)
     java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
     java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
     java.base/java.lang.Thread.run(Thread.java:1583)

    This can be reproduced by consecutive WAR deployments, so that the memory usage increases after each time the service is restarted.

    I was wondering if the JDBC driver could be enhanced to help close all resources.



    ------------------------------
    Kristian Arlt
    ------------------------------


  • 2.  RE: Informix JDBC driver cleanup bug - memory leak

    Posted Wed June 12, 2024 01:50 AM

    What version of the JDBC driver?



    ------------------------------
    Øyvind Gjerstad
    Developer/Architect
    PostNord AS
    ------------------------------



  • 3.  RE: Informix JDBC driver cleanup bug - memory leak

    Posted Wed June 12, 2024 04:28 AM

    The latest found on mvnrepository: 

    <dependency>
        <groupId>com.ibm.informix</groupId>
        <artifactId>jdbc</artifactId>
        <version>4.50.10.1</version>
    </dependency>



    ------------------------------
    Kristian Arlt
    ------------------------------



  • 4.  RE: Informix JDBC driver cleanup bug - memory leak

    Posted Wed June 12, 2024 04:42 AM

    Ok, we are using 4.50.9. Not exactly same environment, though, we are using jboss, not tomcat. Haven't noticed this problem.



    ------------------------------
    Øyvind Gjerstad
    Developer/Architect
    PostNord AS
    ------------------------------



  • 5.  RE: Informix JDBC driver cleanup bug - memory leak
    Best Answer

    Posted Thu June 13, 2024 03:27 AM

    Hello Kristian,

    The connection cleaner thread has following properties:
    IFMXCONNECTION_CLEANER_THREADS (defaults to 0)
    IFMXCONNECTION_CLEANER_DELAY_MAXIMUM (defaults to 15000 msec/15 sec)
    You can try to disalbe the connection cleaner thread with following Parameter in the connection string/URL:
    ;IFMXCONNECTION_CLEANER_THREADS=0

    HTH,
    Cheers,
    Markus



    ------------------------------
    Markus Holzbauer
    ------------------------------



  • 6.  RE: Informix JDBC driver cleanup bug - memory leak

    Posted Thu June 13, 2024 03:41 AM

    From which version of the JDBC driver are these connection cleaner threads used?



    ------------------------------
    Øyvind Gjerstad
    Developer/Architect
    PostNord AS
    ------------------------------



  • 7.  RE: Informix JDBC driver cleanup bug - memory leak

    Posted Thu June 13, 2024 03:46 AM

    I think the feature is available since JDBC 4.10.JC12. Maybe someone from IBM can correct me...

    Cheers,
    Markus



    ------------------------------
    Markus Holzbauer
    ------------------------------



  • 8.  RE: Informix JDBC driver cleanup bug - memory leak

    Posted Thu June 13, 2024 11:59 AM

    The cleaner thread was introduced way back, before 4.10.JC6 even if I recall. But the ability to turn it off was introduced much later. Currently the default value is 1 thread. The point of this thread was to help with developers who didn't understand they needed to close connections after they used them (think back before try-with-resources feature or web frameworks like Spring were built in java).

    My opinion the feature should not ever be enabled if you are using a framework and web servers like Tomcat or Spring to manage connections for you. I would just shut it off since those frameworks ensure connections are correctly closed when needed and pooled when wanted.

    The lingering thread is a defect/bug but most of the time you don't even want it running in the first place so that's the easier solution for you I think. Should the default be 0?  Probably yes, but unsure if someone will change it. Changing default behavior is always a tricky subject. 

    Hope this helps!



    ------------------------------
    Brian Hughes
    ------------------------------



  • 9.  RE: Informix JDBC driver cleanup bug - memory leak

    Posted Tue February 04, 2025 02:48 PM

    I think there could be a possible memory leak.

    Even the threads are not started witch I agree is the best, I see lot of weak references.

    Looking at code:

    Even cleaner will not be created, queueOfConnection gets a connection on every creation.
    On a long living application that creates/closes many connections this queue grows to infinite.

    I think.

    /* 588 */ protected static final BlockingQueue<DelayedWeakReference<IfxSqliConnect>> queueOfConnections = new DelayQueue<>();

    static synchronized <T extends IfxSqliConnect> void ensureConnectionMonitorThreadIsRunning(T connection) {

    /* 597 */ long delay = IfxConnectionProperty.IFMXCONNECTION_CLEANER_DELAY_MAXIMUM.getLongValue((IfxSqliConnect)connection);

    /* 598 */ queueOfConnections.offer(new DelayedWeakReference(connection, delay));

    /* */

    /* 600 */ if (cleaner == null) {

    /* 601 */ int nThreads = IfxConnectionProperty.IFMXCONNECTION_CLEANER_THREADS.getIntValue((IfxSqliConnect)connection);

    /* 602 */ if (nThreads > 0) {

    /* 603 */ cleaner = Executors.newFixedThreadPool(nThreads, new IfxSqliConnectCleanerThreadFactory());

    /* 604 */ for (int i = 0; i < nThreads; i++)

    /* 605 */ cleaner.execute(new IfxSqliConnectCleaner());

    /* */ }

    /* */ }

    /* */ }

    Class Name                                                                                                               | Shallow Heap | Retained Heap
    --------------------------------------------------------------------------------------------------------------------------------------------------------
    com.informix.jdbc.IfxSqli @ 0x6e0f7b7d0                                                                                  |          312 |     2,101,048
    '- prot com.informix.jdbc.IfxStatement @ 0x6e0f7b748                                                                     |          136 |           376
       '- referent java.lang.ref.WeakReference @ 0x6e0f7b728                                                                 |           32 |            32
          '- weakReferenceStmt com.informix.jdbc.IfxSqliConnect$StmtList @ 0x6e0f7ba68                                       |           24 |            56
             '- [31] java.lang.Object[160] @ 0x69f9c9820                                                                     |          656 |         3,008
                '- elementData java.util.Vector @ 0x68de64be0                                                                |           32 |         3,040
                   '- stmtList com.informix.jdbc.IfxSqliConnect @ 0x68de601c8                                                |          376 |        14,208
                      '- referent com.informix.util.DelayedWeakReference @ 0x71c13de88                                       |           48 |            48
                         '- [56] java.lang.Object[343] @ 0x6cbe0def8                                                         |        1,392 |        14,352
                            '- queue java.util.PriorityQueue @ 0x684c184a0                                                   |           32 |        14,384
                               '- q java.util.concurrent.DelayQueue @ 0x6849d7c00                                            |           32 |        14,520
                                  '- queueOfConnections class com.informix.jdbc.IfxSqliConnect @ 0x6849e5dc8                 |          336 |        37,944
                                     |- <class> com.informix.jdbc.IfxSqliConnect @ 0x6b53cc3b0                               |          376 |        10,792
                                     |  |- <Java Local> java.lang.Thread @ 0x6849d7b00  IfxSqliConnectCleaner-Thread-1 Thread|          104 |         4,784
                                     |  |- jconn com.informix.jdbc.IfxStatement @ 0x71dfa3078                                |          136 |           376
                                     |  |- conn com.informix.jdbc.IfxSqli @ 0x71dfa31b0                                      |          312 |         2,504
                                     |  |- conn com.informix.jdbc.IfxResultSet @ 0x71dfa5300                                 |          104 |           104
                                     |  |- conn com.informix.jdbc.IfxRowColumn @ 0x71dfaa008                                 |           48 |            48
                                     |  '- Total: 5 entries                                                                  |              |              
                                     |- <class> com.informix.jdbc.IfxSqliConnect @ 0x714f85588                               |          376 |         8,832
                                     |- <class> com.informix.jdbc.IfxSqliConnect @ 0x6950c8ec0                               |          376 |        16,040
                                     |- <class> com.informix.jdbc.IfxSqliConnect @ 0x6a09d5bb8                               |          376 |        13,168
                                     |- <class> com.informix.jdbc.IfxSqliConnect @ 0x6c3283988                               |          376 |        15,832
                                     |- <class> com.informix.jdbc.IfxSqliConnect @ 0x6eb3e70f8                               |          376 |         7,392
                                     |- <class> com.informix.jdbc.IfxSqliConnect @ 0x709f0db10                               |          376 |        10,688
                                     |- <class> com.informix.jdbc.IfxSqliConnect @ 0x70c3c3250                               |          376 |        10,664
                                     '- <class> com.informix.jdbc.IfxSqliConnect @ 0x70cd302f8                               |          376 |         9,064
    --------------------------------------------------------------------------------------------------------------------------------------------------------



    ------------------------------
    Xavier Escote
    ------------------------------



  • 10.  RE: Informix JDBC driver cleanup bug - memory leak

    Posted Mon June 17, 2024 06:11 AM

    Thank you @Markus Holzbauer for the quick reply, I added the IFMXCONNECTION_CLEANER_THREADS parameter to our connection string and the Warning is gone. After also analyzing the memory usage, Tomcat memory usage stays steady.



    ------------------------------
    Kristian Arlt
    ------------------------------



  • 11.  RE: Informix JDBC driver cleanup bug - memory leak

    Posted Tue February 04, 2025 02:48 PM
      |   view attached

    The driver has a memory leak.

    When cleaner is not started it's internal queue stores connections (should not).
    As the cleaner will never run, connections will be keep in the queue forever.

    See test case.

    Output:

    Queue size:1
    Queue size:2
    Queue size:3
    Queue size:4
    Queue size:5
    Queue size:6
    Queue size:7
    Queue size:8
    Queue size:9
    Queue size:10



    ------------------------------
    Xavier Escote
    ------------------------------

    Attachment(s)

    java
    mleak.java   1 KB 1 version