2017-01-09 1 views
1

Я бег TomEE (вида Tomcat) сервер на Java 8 и используя Titan 1.0.0 с Кассандрой бэкэндом и индексом Elasticsearch в моей базе данных. В моей среде разработки с небольшим пользовательским подключением все работает отлично, но на моем рабочем сервере со многими пользователями, связанными с большим доступом к db, у нас есть проблема с утечками памяти, вероятно, из-за того, что кеш-диаграмма Titan или что-то подобное Titan. У меня есть размер кучи размером 4 ГБ, и после более чем 10 часов работы выделенная память на куче растет до максимума (~ 300 Мбит/ч в час), и это приводит к тому, что GC (Garbage Collector) больше не может очищать и остается работать непрерывно, что заставляет экземпляр сервера быть неактуальным. Использование VisualVM я сделал некоторые профилирование памяти и те мои скриншоты: Allocated memory graph
Heap histogram Любой подсказывают, как можно это исправить или найти способ, чтобы исследовать этот вопрос более подробно? Может быть, некоторые GC-параметры могут помочь нам в этом случае?Titan 1.0.0 график кэш-память просачивается

ответ

2

Я видел эти проблемы раньше на Titan 1.0 с Cassandra. Две вещи, чтобы проверить:

Открытие и закрытие Graph

вы открываете другую транзакцию на графике для каждого пользователя или различных графиков для каждого пользователя? т.е. вы делаете:

(1)

//User 1 Logs in 
graph = TitanFactory.open(config); 
soStuffWithGraph(graph); 
//User 2 Logs in 
graph = TitanFactory.open(config); 
soStuffWithGraph(graph); 

или

(2)

graph = TitanFactory.open(config); 
//User 1 Logs in 
soStuffWithGraph(graph); 
//User 2 Logs in 
soStuffWithGraph(graph); 

подхода (1) означает, что каждый пользователь получает свое собственное подключение к графике с их собственный объект графа. Это очень тяжело и приводит к большему использованию памяти.

Подход (2) означает, что каждый пользователь использует одно и то же соединение, но разные транзакции. Это, на мой взгляд, предпочтительнее. Примечание: предполагается, что пользователи находятся на разных потоках.

Долгосрочные Сделки

Это проблема, которую я имел в результате которой в подобных проблем ГЦ к себе. Я слишком долго держал транзакции живыми. Чтобы ускорить запрос Titan, кэш много, и я не думаю, что он очищает кеш, если транзакция не закрыта. Поэтому в идеале у вас должно быть что-то вроде:

graph = TitanFactory.open(config); 
//User 1 Logs in 
soStuffWithGraph(graph); 
graph.tx().close(); 
//User 2 Logs in 
soStuffWithGraph(graph); 
graph.tx().close(); 

где каждая транзакция закрыта после того, как пользователь с ней выполнен.

+0

Я использую второй подход. У меня есть одно открытое соединение с графиком и открытие новой транзакции «TitanTransaction tt = graph.newTransaction()» для каждого пользовательского запроса. Каждая транзакция короткая (добавляет или обновляет одну или две вершины или ребра ИЛИ данные запроса из вершин), а в конце транзакции всегда передается 'tt.commit()' или roll-backed 'tt.rollback()' в случае отказа (перед выбросом некоторого исключения) – OctopusSD

+0

Используете ли вы 'graph.newTransaction()', тогда вы создаете [многопоточные транзакции] (http://s3.thinkaurelius.com/docs/titan/1.0.0/tx.html# multi-thread-tx), который создает целый новый объект обработки транзакций, который также довольно тяжелый и всегда открыт.Если вы * явно * создаете один для каждого пользователя, тогда вам обязательно нужно называть 'tt.close()' в конце. В противном случае он останется открытым. –

+1

Из Титана [документация] (http://s3.thinkaurelius.com/docs/titan/1.0.0/index.html) и [javadoc] (http://titan.thinkaurelius.com/javadoc/1.0.0/) Я думал, что 'tt.commit()' и 'tt.rollback()' закроют транзакцию, но после добавления 'tt.close()' рядом с каждым фиксацией и откатом он решает наши утечки памяти. – OctopusSD

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