Comments 20
Самое главное-то и не рассказали: был ли этот код потом убран — или так и остался на продашкене? :)
0
Hibernate = зло
-2
Но как узнать, где порождается такое большое количество объектов? Искать по коду? Не вариант, придется делать поиск по всей системе, а времени в обрез – заказчик уже весь синеет.
Я конечно извиняюсь, но вроде бы, поднятие общих бизнес сущностей выносят в отдельные классы, тогда и связность системы понизилась бы, поиск с модификацией кода работающего с entity стали куда проще, да и необходимость у программистов сто первый раз писать велосипед, вроде того поднятия entity не было бы. Плюс часто делают свои обертки над классами JPA'а, вроде entityManager'a, чтобы, например, было проще отлаживать и профилировать поднятие entity (на самом деле, так ещё куча других полезных вещей). Тогда не нужно было делать всех этих хаков с конструктором.
0
Хорошо, допустим, сущность «поднимается» всего в одном методе, а метод вызывается в 100500 местах. Что-то изменилось от замены конструктора на метод? Стало ли проще найти то место, где этот метод вызывается чаще всего?
0
Ну, смотрите делаем, например, грубо говоря такой сервис
Теперь нам не нужно искать вообще все Payment'ы, достаточно сделать поиск по getAllPayment и getPaymentByQuery и понять где программисты промахнулись. Крайне редко проблема будут в цикле с getPaymentById.
public interface ServicePayment {
Payment getPaymentById(String id);
Payment getAllPayment();
Payment getPaymentByQuery(String query);
}
Теперь нам не нужно искать вообще все Payment'ы, достаточно сделать поиск по getAllPayment и getPaymentByQuery и понять где программисты промахнулись. Крайне редко проблема будут в цикле с getPaymentById.
0
Ну вот нашли вы 100400 мест, где используются getAllPayment или getPaymentByQuery. Что дальше?
+1
Если бы нашел 100400 мест, где используются getAllPayment, прибил бы архитектора. Шутка. Вызовы getAllPayment на 2 млн. entity, скорее всего могут должны использоваться только для задач интеграции, обслуживание БД и т.п. Если такой метод используется в обычных модулях это уже повод понять зачем.
Если есть куча мест где используется getPaymentByQuery(«name = ?»), то это повод выделить его в отдельный метод getPaymentByName, создать индекс по полю name, сделать тест производительности метода на реальной базе и т.д. Также для всех подобных методах, в результате большинство частых запросов можно будет выделить в отдельные методы. А дальше всегда можно использовать профайл и т.п. методики на отдельных методах. Метод getPaymentByQuery имеет смысл именно для действительно уникальных случаев и опять-таки ловится профайлером, логированием времени работы и т.п. методами
Ну, например что будет узнаете ли вы когда нибудь, что у вас используется в 100400 мест запросы вида «Payment.name = ?», но индекс по поля name вы сделать забыли, отчего вся ваша система дико тормозит? Ни один профайлер не сможет собрать такие запросы из 100400 мест, насколько я знаю.
Если есть куча мест где используется getPaymentByQuery(«name = ?»), то это повод выделить его в отдельный метод getPaymentByName, создать индекс по полю name, сделать тест производительности метода на реальной базе и т.д. Также для всех подобных методах, в результате большинство частых запросов можно будет выделить в отдельные методы. А дальше всегда можно использовать профайл и т.п. методики на отдельных методах. Метод getPaymentByQuery имеет смысл именно для действительно уникальных случаев и опять-таки ловится профайлером, логированием времени работы и т.п. методами
Ну, например что будет узнаете ли вы когда нибудь, что у вас используется в 100400 мест запросы вида «Payment.name = ?», но индекс по поля name вы сделать забыли, отчего вся ваша система дико тормозит? Ни один профайлер не сможет собрать такие запросы из 100400 мест, насколько я знаю.
+1
Но вы понимаете, что в сумме по всем методам число мест, откуда они вызываются, будет постоянным, как их не переименовывай?
PS убийство архитектора в отсутствии машины времени проблему не решает.
PS убийство архитектора в отсутствии машины времени проблему не решает.
0
А профайлер бы не показал наиболее часто вызываемые и «долгоиграющие» методы?
0
Можно было бы похожее сделать с помощью AspectJ и не писать в лог, а писать в set сам StackTraceElement и сделать каунтер. Плюсы — без модификации кода и можно поймать точку вызова конструктора
0
Это если AspectJ у вас под рукой и есть тот, кто знает как им пользоваться… Можно при желании и свой профилировщик написать…
+1
Так и делает мой коллега.
Он есть всегда и со всеми зависимостями
org.aspectjaspectjrt1.8.4
И научиться пользоваться им гораздо проще чем разгребать гигабайты логов!
Это если AspectJ у вас под рукой
Он есть всегда и со всеми зависимостями
org.aspectjaspectjrt1.8.4
И научиться пользоваться им гораздо проще чем разгребать гигабайты логов!
0
А можно было бы просто подключить github.com/devexperts/aprof
+3
Такая же ситуация была, с аналогичным скриптом. Тоже горе хапнули
0
А почему не использовали Flight Recorder из Java Mission Control ?
Без видимых снижений производительности (всего около 2%) можно на боевом окружении увидеть проблемы с памятью:
— Allocation By Class — как раз то что вы написали
— Allocation By Thread
Без видимых снижений производительности (всего около 2%) можно на боевом окружении увидеть проблемы с памятью:
— Allocation By Class — как раз то что вы написали
— Allocation By Thread
+1
Sign up to leave a comment.
Рассказ о том, как я с помощью логов нашел «пожирателя» памяти