2012-07-17 3 views
0

Я хочу поделиться странным примером. При производстве наше приложение бросает исключение OOM, мы взяли кучу кучи и начали анализировать, что позже мы обнаружили проблему с экземпляром com.mchange.v2.c3p0.stmt.PerConnectionMaxOnlyStatementCache. Размер этого объекта составляет около 50% от размера кучи. Приложение работает с миллиардами пользователей, и сервер снова и снова опускается.Ошибка производительности с кеш-файлом c3p0:

Это приложение работает на 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 

Из инструмента мониторинга кучи мы получаем следующее сообщение

один экземпляр «com.mchange.v2.c3p0.stmt.PerConnectionMaxOnlyStatementCache» нагруженный «org.apache.catalina.loader.WebappClassLoader @ 0x82f1c58 "занимает 72 970 824 (57,75%) байт. Память накапливается в одном экземпляре «com.mchange.v2.c3p0.stmt.PerConnectionMaxOnlyStatementCache» загружен «org.apache.catalina.loader.WebappClassLoader @ 0x82f1c58»

Пожалуйста, посоветуйте пожалуйста: - Что может быть причиной этот экземпляр принимает такую ​​огромную память? Мы работаем с правильной конфигурацией c3p0? Каковы рекомендуемые конфигурации для тяжело нагруженного приложения?

Заранее спасибо

+1

Вы сказали, что используете Tomcat. Почему вы используете свой собственный C3P0 вместо пула соединений Tomcat? – jpkrohling

+0

попробуйте установить эти параметры

ответ

-1

Try BoneCP для пула соединений высокой производительности, он решает множество производительности ориентированных задач C3P0 и Apache ДБХПА.

+0

Спасибо за ваш ответ! Но, к сожалению, мы не можем изменить приложение для использования BoneCP, приложение работает в слишком большом количестве клиентов. Нам нужно найти способ обойти это. Настройки кот заключаются в следующем maxHttpHeaderSize = "8192" MaxThreads = "500" MinSpareThreads = "50" maxSpareThreads = "1000" enableLookups = "ложно" redirectPort = "8443" acceptCount = "150" ConnectionTimeOut = "20000" disableUploadTimeout = "true" – user1451493

2

Вы установили maxStatementsPerConnection = 50 и maxPoolSize = 150. Это означает, что в кэше операторов может быть до 7500 открытых сообщений в любой момент времени, включая объем памяти любых ресурсов, которые ваш драйвер связывает с заявлениями. Вы в основном просите c3p0 использовать целую массу памяти, исходя из теории о том, что стоимость памяти низкая по сравнению с эксплуатационными затратами на подготовку заявления.

Во-первых, это может быть неверно, и в этом случае кэширование Statement является проигравшим вообще, и вы просто не должны его использовать. Вы должны сравнить свое приложение с maxStatements и maxStatementsPerConnection, установленным на ноль, чтобы проверить, действительно ли вы получаете выгоду от кэширования Statement, если вы еще этого не сделали. Для драйверов, которые кэшируют много разбора и подготовки в объектах PreparedStatement, кэширование Statement может быть большой помощью. Но вы сталкиваетесь с компромиссом между памятью кеша и преимуществом производительности при наличии предварительно кэшированных заявлений. Совершенно очевидно, что даже если кэширование Statement полезно для вашей производительности, вы превысили тот момент, когда преимущества превышают затраты.

Сколько из 150 подготовленных заявлений в вашем приложении часто используется? Можете ли вы сделать это число меньше, желательно намного меньше, ожидая, что более редко используемые Заявления выйдут из кеша и избавятся от них? В качестве альтернативы вы можете оставить этот номер один, но объедините maxStatementsPerConnection с глобальным параметром maxStatements (установите на что-то меньшее, чем неявное 7500, которое вы используете в настоящее время). Если вы объедините maxStatementsPerConnection и maxStatements, каждому соединению будет разрешено иметь до maxStatementsPerConnection, в то время как пул невелик, но по мере того, как пул становится большим, а площадь памяти становится опасной, глобальный предел Statement приведет к запуску менее недавно использованных операторов выключение кэша для сохранения памяти.

Я надеюсь, что это поможет!

+0

Привет, Стив, спасибо – user1451493

0

Это потому, что вы дали maxIdleTime = 0.

Установка максимального значения maxIdleTime на ненулевое значение позволяет C3P0 удалять соединения из пула и освобождать ресурсы базы данных.

Это никогда не произойдет, если maxIdleTime установлен в 0

.

Поэтому я считаю, что ни одно из ваших соединений не удаляется из пула. Вот почему он идет огромным размером кучи.

Дополнительная информация click here.

Смежные вопросы