【问题标题】:Performance issue with c3p0 cache object:c3p0 缓存对象的性能问题:
【发布时间】:2012-07-16 03:39:52
【问题描述】:

我想分享一个奇怪的例子。在生产中,我们的应用程序抛出 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 配置运行? 对于负载较重的应用程序,推荐的配置是什么?

提前致谢

【问题讨论】:

  • 您说您使用的是Tomcat。那你为什么要使用自己的 C3P0 而不是 Tomcat 的连接池?
  • 尝试设置这些参数

标签: hibernate c3p0


【解决方案1】:

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

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

在您的应用中,这 150 条准备好的语句中有多少是经常使用的?你能不能让这个数字更小,最好更小,期望更不常用的语句会从缓存中删除并很好地摆脱它们?或者,您可以不理会该数字,但将 maxStatementsPerConnection 与全局 maxStatements 设置(设置为小于您当前使用的隐式 7500 的值)结合使用。如果结合 maxStatementsPerConnection 和 maxStatements,当池较小时,每个 Connection 最多可以有 maxStatementsPerConnection,但是随着池变大并且内存占用成为危险,全局 Statement 限制将导致最近使用较少的 Statements 启动退出缓存以保留内存。

我希望这会有所帮助!

【讨论】:

    【解决方案2】:

    这是因为你给了 ma​​xIdleTime=0

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

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

    .

    所以我相信您的所有连接都没有从池中删除。 这就是为什么它的堆大小越来越大。

    更多参考click here

    【讨论】:

      【解决方案3】:

      试试BoneCP一个高性能的连接池,它解决了很多c3p0和Apache DBCP的性能问题。

      【讨论】:

      • 感谢您的回复!但不幸的是,我们无法将应用程序更改为使用 BoneCP,应用程序存在于太多客户端。我们需要想办法解决这个问题。 tomcat设置如下 maxHttpHeaderSize="8192" maxThreads="500" minSpareThreads="50" maxSpareThreads="1000" enableLookups="false" redirectPort="8443" acceptCount="150" connectionTimeout="20000" disableUploadTimeout="true "
      猜你喜欢
      • 1970-01-01
      • 2014-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-18
      • 1970-01-01
      • 2011-12-04
      • 1970-01-01
      相关资源
      最近更新 更多