Hibernate c3p0缓存对象的性能问题:

Hibernate c3p0缓存对象的性能问题:,hibernate,c3p0,Hibernate,C3p0,我想分享一个奇怪的例子。在生产环境中,我们的应用程序引发OOM异常,我们进行了堆转储并开始分析,后来我们发现com.mchange.v2.c3p0.stmt.PerConnectionMaxOnlyStatementCache实例存在问题。此对象的大小约为堆大小的50%。应用程序运行时有数十亿用户,服务器一次又一次地停机 此应用程序在tomcat上运行,其中tomcat连接器最多允许300个并发请求,以下是c3p0配置 jdbc.hibernate.c3p0.minPoolSize=2 jdbc

我想分享一个奇怪的例子。在生产环境中,我们的应用程序引发OOM异常,我们进行了堆转储并开始分析,后来我们发现com.mchange.v2.c3p0.stmt.PerConnectionMaxOnlyStatementCache实例存在问题。此对象的大小约为堆大小的50%。应用程序运行时有数十亿用户,服务器一次又一次地停机

此应用程序在tomcat上运行,其中tomcat连接器最多允许300个并发请求,以下是c3p0配置

jdbc.hibernate.c3p0.minPoolSize=2
jdbc.hibernate.c3p0.maxPoolSize=150
jdbc.hibernate.c3p0.maxIdleTime=0
jdbc.hibernate.c3p0.maxStatementsPerConnection=50
jdbc.hibernate.c3p0.numHelperThreads=6
从堆监视工具中,我们得到以下消息

“org.apache.catalina.loader.WebappClassLoader@0x82f1c58”加载的“com.mchange.v2.c3p0.stmt.PerConnectionMaxOnlyStatementCache”的一个实例占用72 970 824(57,75%)字节。内存在“org.apache.catalina.loader.WebappClassLoader@0x82f1c58”加载的“com.mchange.v2.c3p0.stmt.PerConnectionMaxOnlyStatementCache”的一个实例中累积

请告知:- 这个实例占用如此巨大的内存是什么原因? 我们是否使用正确的c3p0配置运行? 对于重载应用程序,推荐的配置是什么


提前感谢您尝试使用高性能连接池,它解决了c3p0和Apache DBCP的许多面向性能的问题。

您已经设置了MaxStatementSpercConnection=50和maxPoolSize=150。这意味着语句缓存在任何时候都可能有多达7500个打开的语句,包括驱动程序与语句关联的任何资源的内存占用。您基本上要求c3p0使用大量内存,理论上,与准备语句的性能成本相比,内存成本较低

首先,这可能根本不是真的,在这种情况下,语句缓存通常是失败的,您不应该使用它。您应该将maxStatementsPerConnection和maxStatementsPerConnection都设置为零,以测试您是否真的从语句缓存中获益(如果您还没有)。对于在PreparedStatement对象中缓存大量解析和准备的驱动程序,语句缓存可以提供很大帮助。但是,您需要在缓存的内存占用和预缓存语句的性能优势之间进行权衡。很明显,即使语句缓存有助于提高性能,您也已经超过了收益大于成本的程度

在你的应用程序中,150条准备好的语句中有多少经常被使用?你能让这个数字更小,最好小得多,期望更多很少使用的语句会从缓存中掉出来,很好地摆脱它们吗?或者,您可以不使用该数字,而是将maxStatementsPerConnection与全局maxStatements设置相结合(设置为小于当前使用的隐式7500)。如果将maxStatementsPerConnection和maxStatements结合使用,则在池较小时,每个连接最多允许有maxStatementsPerConnection,但随着池变大,内存占用成为一种危险,全局语句限制将导致最近使用较少的语句开始从缓存中删除以保留内存


我希望这有帮助

这是因为您给出了maxIdleTime=0

将maxIdleTime设置为非零值允许C3P0从池中删除连接并释放数据库资源

当maxIdleTime设置为0时,这种情况永远不会发生

所以我相信你们的关系没有一个是从池中移除的。 这就是为什么它在堆大小上变得越来越大


更多参考。

您说过您正在使用Tomcat。那么为什么您要使用自己的C3P0而不是Tomcat的连接池呢?请尝试设置这些参数,谢谢您的回复!但不幸的是,我们无法将应用程序更改为使用BoneCP,因为应用程序在太多客户端上运行。我们需要找到一个解决办法。tomcat设置如下maxHttpHeaderSize=“8192”maxThreads=“500”minSpareThreads=“50”maxSpareThreads=“1000”enableLookups=“false”redirectPort=“8443”acceptCount=“150”connectionTimeout=“20000”disableUploadTimeout=“true”