Something I've noticed by looking deeper at the heap dump :
I have 158 instances of PreparedStatementCache !
How is this possible for a single datasource ?
Each PrepaparedStatementCache instance references up to100 prepared statement, which corresponds to what is defined for the datasource :
<statement>
<track-statements>true</track-statements>
<prepared-statement-cache-size>100</prepared-statement-cache-size>
<share-prepared-statements>true</share-prepared-statements>
</statement>
So 158*100 = 15 800 possible instances of prepared statements which correlates with the the 14894 instances of T4CPreparedStatement I have in my heap.
So it seems something is wrong with the prepared statement cache which is duplicated.