код ошибки out of memory браузер
Недостаточно памяти для загрузки страницы в Google Chrome
Если недостаточно памяти для загрузки страницы в Хроме, то ничего удивительного в этом нет. Всем известно, что этот веб-обозреватель тоннами пожирает оперативную память. А если серьезно, то у этой ошибки есть вполне конкретные причины, которые и будут рассмотрены в нашем материале.
Подробности
Вообще, если на вашем компьютере менее 4 ГБ оперативной памяти, то использовать на нем Google Chrome не рекомендуется. Хотя он и на компьютерах с 4 ГБ RAM на борту способен показывать такие «фокусы».
Как правило, определить то, что вызвало данную ошибку не получается. Поэтому приходится применять все возможные способы для исправления ошибки. Их не так уж и много, так что вполне можно попробовать все (для профилактики).
Сейчас мы начнем рассматривать те, которые наиболее вероятно помогут с решением проблемы. А потом перейдем к второстепенным. Последние предназначены для того, чтобы такой ошибки больше не случалось. Итак, приступим.
Отключаем аппаратное ускорение
Аппаратное ускорение – штука хорошая. Оно заставляет картинки и видео рендериться при помощи аппаратных ресурсов компьютера. А еще Хром умеет рендерить с помощью этой опции целые страницы. Те, которые он загружает.
Но эта штука хороша только в том случае, если оперативной памяти на ПК хватает. А вот если ее почти нет, то опцию лучше отключить, так как она требует изрядного количества ОЗУ. Вот подробная инструкция по отключению опции аппаратного ускорения.
После рестарта нужно какое-то время поработать в нем и проверить его стабильность. Если такие вылеты не прекращаются, то нужно переходить к следующей главе данного материала.
Отключаем расширения
Всевозможные дополнения, конечно, расширяют функционал браузера и делают работу с ним проще и интереснее. Но не стоит забывать, что эти плагины требуют довольно много оперативной памяти. И если у вас их установлено много, то ОЗУ точно будет не хватать.
К тому же, некоторые расширения могут конфликтовать друг с другом и поэтому потребляют много ресурсов. Наиболее правильным шагом будет отключение расширений. Сделать это можно в самом браузере. Вот подробная инструкция.
После отключения плагинов нужно обязательно перезапустить веб-обозреватель. Только тогда изменения вступят в силу. После рестарта нужно проверить стабильность работы браузера. Если ничего не помогло, то переходим к следующей главе.
Но перед этим стоит отметить, что некоторые расширения все-таки можно вернуть в том случае, если данный способ не помог. Если у вас их было очень много, то все возвращать не стоит. Нужно остановиться на тех, которые являются самыми полезными. А теперь перейдем к следующему варианту решения проблемы.
Избавляемся от вирусов
Различные вредоносные объекты, хозяйничающие на компьютере, тоже могут уменьшать объем доступной оперативной памяти. Причем весьма существенно. Именно поэтому браузеру может не хватать ОЗУ. А если вирусы не удалять, то последствия могут быть еще более плачевными.
Поэтому нужно периодически проверять ПК на наличие вирусов. Поможет нам в этом любой антивирус, на ваше усмотрение (Kaspersky, ESET, Avast и т. д.). Выполните полное сканирование системы, чтобы программа самостоятельно стерла любые угрозы и вредоносные компоненты.
Заключение
А теперь нужно подвести итоги и сделать соответствующие выводы. Если Гугл Хрому не хватает оперативной памяти для загрузки страницы, то для этого есть определенные причины. Выделять из них основную и применять исключительно один способ не представляется возможным.
Поэтому придется пробовать все вышеописанные варианты. В данном материале представлены самые действенные. Если один метод не помог, то какой-нибудь другой точно поможет. Нужно просто попробовать их все.
Очень важно выполнять все в строгом соответствии с инструкцией. Иначе можно усугубить ситуацию. В целом, в данных инструкциях ничего сложного нет. И с их помощью вы точно решите проблему с веб-обозревателем Гугл Хром.
Многие пользователи ПК во время работы с какой-либо программой могут столкнуться с «вылетом» указанной программы, и появившимся сообщением «Out of memory». Возникшая проблема может иметь множество причин, начиная от банального недостатка памяти на пользовательском ПК, и заканчивая некорректной работой с памятью какой-либо программы.
Причины появления дисфункции
Сообщение «Out of memory» (в переводе дословно «вне памяти», или «недостаточно памяти») обычно возникает при недостатке памяти на пользовательском компьютере. В частности же, в появлении данной ошибки «виновен» следующий набор факторов:
Когда вашему компьютеру не хватает физической R.A.M. памяти, он заимствует часть места на жёстком диске, и создаёт так называемую «виртуальную память». Система временно хранит в такой виртуальной памяти ту часть данных, которая не помещается в памяти обычной. Такие данные обычно хранятся в файле «pagefile.sys», размер которого может увеличиваться или уменьшаться в зависимости от специфики работы вашей ОС. Если на диске будет недостаточно места, файл «pagefile.sys» не сможет расти, и пользователь получит рассматриваемую ошибку.
Как исправить ошибку «Out of memory»
Для решения указанной проблемы рекомендую сделать следующее:
Альтернативным вариантом решения проблемы является установка соответствующего фикса от Майкрософт. Или использование расширений или дополнений для браузера уровня «The Great Suspender» для «Google Chrome», хорошо работающего с ненужными вкладками браузера.
bcdedit/set IncreaseUserVa 3072
И нажмите на ввод, и перезагрузите ваш ПК. Функционал данной команды позволяет выделить пользовательским приложениям 3 гигабайта оперативной памяти для работы. В некоторых системах этого может быть слишком много, потому если после ввода данной команды система начала чаще сбоить, то введите в командной строке от имени администратора:
bcdedit /set IncreaseUserVa 2560 — что позволит задействовать 2,5 гигабайта вместо ранее забронированных 3.
Если ситуацию этим исправить не удалось, верните настройки на состояние по умолчанию:
bcdedit /deletevalue IncreaseUserVa
Установите нужный размер файла подкачки
Заключение
Ошибка «Out of memory» может иметь множество причин, связанных как с физическим недостатком памяти на ПК, так и другими детерминантами, изложенными мной выше. Для решения проблемы советую закрыть ненужные программы (вкладки браузера) на вашем компьютере (тем самым разгрузив его память), а самым эффективным инструментом является установка дополнительной планки памяти на ПК, что в большинстве случаев поможет избавиться от ошибки на вашем компьютере.
Как исправить ошибку «Out of Memory»
Ошибка «Out of Memory» обычно появляется, когда на компьютере запущено много программ, использующих ресурсы, доступные для компьютера. Компьютерная память или ОЗУ (оперативное запоминающее устройство) используется компьютером для быстрого хранения данных для их обработки.
Когда появляется эта ошибка?
Как я уже отмечал выше, запуск сразу нескольких программ может перегрузить объем доступной свободной памяти, что приведет к ошибке «Out of Memory». Это может случиться как с новыми программами, так и с уже запущенными на компьютере программами. Иногда это может произойти, независимо от объема доступной свободной памяти.
Причина ошибки «Out of Memory»
Причина этих ошибок немного сложнее. Подсистема WIN32 Windows имеет ограниченный объем доступной памяти. Если память в куче рабочих столов подсистемы WIN32 используется. Windows может выдавать сообщение об ошибке «Out of Memory».
Компьютеры, работающие не так, как операционные системы Microsoft Windows, не слишком уязвимы. Эта проблема в основном существует для пользователей Windows NT 3.5 и Windows NT 3.1
Как исправить ошибку «Out of Memory»
Чтобы исправить эту проблему, вам необходимо отредактировать свой реестр Windows. Редактирование реестра является рискованным занятием. Действовать нужно с осторожностью, и только строго по инструкции:
Чтобы избежать проблем, тщательно следуйте этим инструкциям.
Отсюда, следуйте этим шагам в зависимости от вашей операционной системы
Для Windows NT:
Для Windows 2000, Windows XP и Windows Server 2003:
Для 32-разрядных операционных систем
Для 64-разрядных операционных систем
Есть свой вариант быстрого решения ошибки «Out of Memory»? Пишите его в форму комментариев к этой статье, и если ваш вариант окажется полезным, мы обязательно дополним руководство.
Top 11 Ways to Fix Google Chrome Is Out of Memory Error on Windows 10
Gaurav Bidasaria
14 Apr 2021
Google Chrome may be widely used my billions across the globe, but it is posthumously notorious for hogging resources. Folks running it on older hardware often state that it slows down and sometimes throws an error code. Many Chrome users report about the ‘out of memory’ error while loading a website recently.
There are two error codes actually that users are greeted with while browsing. One says, ‘Aw, snap! Something went wrong while displaying this web page. Error code: Out of memory.’ And the other error message you may be viewing says, ‘Aw, snap! Google Chrome ran out of memory while trying to display this web page.’
Both the error codes mean the same thing. That Chrome browser is lacking enough memory or resources to fetch and open the web page in question. There could be a few reasons behind this, as we will explore below with solutions.
1. Close Some Tabs
Opening too many tabs in Chrome can lead to a slow browsing experience. Check if you can close some tabs that are no longer needed. That should free some memory for other tabs as well as new tabs.
It is also a good idea to use multiple Chrome windows to open tabs. For example, instead of opening 10 tabs in a single window, you may open 4-5 tabs in one and the remaining in the other Chrome window. In short, manage open tabs when possible to save memory.
2. Try Incognito Mode
We recommend using Incognito mode (press Ctrl+Shift+N to open) because it disables all extensions running in the background. Sometimes, an extension could be causing a conflict.
Open the web page that’s throwing the ‘out of memory’ error and check if it loads in Incognito mode. If yes, then one of the extensions could be at fault. Disable all extensions and enable them one at a time to find out which one is causing the issue.
Step 1: Open a new Chrome tab and go to the below address.
Step 2: Click on the toggle to enable/disable the extension and select Remove button to uninstall the Chrome extension.
3. Restart Chrome
Before you restart Chrome, don’t forget to save all your work to avoid losing it. Once done, close all open Chrome windows along with tabs, wait a few moments, and then relaunch Chrome.
4. Manage Extensions
We discussed how an old, incompatible extension could be causing a memory leak. But installing too many extensions can also lead to memory issues on Chrome as they tend to consume a lot of resources. We saw above how you can uninstall or remove a Chrome extension but instead, you could also manage extensions and disable/enable them quickly when required without messing with browser settings.
Ironically, that involves installing another extension, but it will make your life easier.
Also on Guiding Tech
How to Uninstall Chrome Apps and Extensions on Windows and Mac
5. Clear Browser Cache and Cookies
Clearing browser cache and cookies can help improve browser performance and fix several issues like the ‘out of memory’ error that users are facing. There is a hidden trick to clear cache and cookies for a single site, the one that’s not loading on your browser, or you could clear data for all sites from browser settings. Don’t forget to save all open tabs and work before you clear cache and cookies if you aren’t sure what happens afterward.
6. Clear Temp Files
Website cache and cookies help to load the respecive sites quickly. And Chrome saves some temporary files on your Windows computer, which can accumulate to several GBs over time. You remove those temporary and old files to make Chrome get a fresh batch of data and prevent any conflicting errors.
Windows 10 comes with a built-in option to clear temporary files from each drive on your computer. You need to clear it for the drive where you have installed Chrome. That’s most probably the default drive which is usually the C drive. You may use a third-party app if you prefer one.
7. Run Chrome Cleanup Tool
Google has released a dedicated tool to fix many common Chrome browser-related issues. It is free to download, and you will find the link shared below. Google recommends users run the utility tool once to fix the memory and page crash-related issues.
8. Disable Hardware Acceleration
Step 1: Go to Settings > Advanced > System or enter the path below in the address bar.
Step 2: Disable the ‘Use hardware acceleration when available’ option.
Check again if you can open the web page or still get the ‘out of memory’ error code.
9. New User Profile
The Chrome user profile may have gone corrupt. Creating a new profile may fix the memory problem. The steps are simple and won’t take more than a few minutes to implement.
Also on Guiding Tech
Top 7 Ways to Remove Chrome Extensions Permanently
10. Reinstall Chrome
Cache and temporary files that collect over time could lead to errors. When users uninstall an app on Windows, it leaves registry entries and other files behind which can cause conflicts too. This is why we recommend a clean reinstall.
You can use reliable apps such as Revo Uninstaller to uninstall apps on Windows and also delete leftover files.
You can check the current version of Chrome installed on your computer at the below address.
Once done, you are ready to download and install the latest stable version of Chrome.
11. Increase Memory Limit
This is for advanced users, and most of you won’t have to resort to this. Google has set a memory limit of 512MB for 32-bit and 1.4GB for 64-bit systems. Using ‘—max_old_space_size’, you can bump this memory limit later to 1GB for 32-bit and 4GB for 64-bit systems. Note that these memory limit values are for individual tabs and not windows.
Based on the ongoing discussions to remove this 4GB limit, you can expect a solution in the future. The reason is that raising the limit would affect only a small number of users. A few years ago, most web apps didn’t use that much memory either, but now things are different. Some developers also noted that capping the memory at 4GB prevented certain exploits, thereby protecting the users.
However, things are different now and users have more powerful machines running Chrome and web apps have come a long way. Hopefully, the Google Chrome’s development team increases the memory limit in the subsequent builds.
One way to increase memory limit is by changing the Chrome link address from:
Again, there are many variables involved as different users have different versions, RAM, OS, etc. making it difficult to offer a one-size-fits-all solution.
Also on Guiding Tech
# Google Chrome
Down the Memory Lane
You may see the ‘out of memory’ error on Chrome if you have too many tabs being open at the same time or too many extensions running in the background. The solutions mentioned above should help you fix the problem and you should be back to browsing your favorite sites in no time.
Next up: Firefox is making its way into the Chrome dominant browser market with Quantum. Is it worth making a shift from Chrome to Firefox? Check it out.
Last updated on 14 Apr, 2021
The above article may contain affiliate links which help support Guiding Tech. However, it does not affect our editorial integrity. The content remains unbiased and authentic.
Read Next
7 Best Ways to Fix Google Chrome Untitled Blank Page
# Google # Chrome showing an untitled blank page might leave you in a head-scratching situation. Let’s troubleshoot the issue once and for all.
Top 10 Ways to Fix Google Chrome Keeps Freezing or Crashing on Windows 10
# Chrome keeps on crashing or freezing on you? Check out these 10 best ways to troubleshoot Chrome crashes on # Windows 10.
9 Best Ways to Fix Google Chrome Not Loading Pages in Windows 10
# Google Chrome struggling to load pages in Windows-powered computer? Here are some common and uncommon solutions to fix Chrome page load and speed issues.
A Complete Guide to Fixing YouTube Playback Error
Are you facing the infamous # YouTube playback error issue? Here’s our guide to troubleshoot the issue.
9 Best Fixes for Downloads Keep Pausing in Chrome on Android
Are you unable to # download anything from Google # Chrome on # Android? Here’s how to fix # Chrome downloads keep pausing or not working on Android
7 Best Ways to Fix Microsoft Edge Can’t Reach This Page Error
# Microsoft Edge’s ‘hmm we can’t reach this page’ error might throw you off from the browsing experience. Follow the mentioned steps in the post and troubleshoot the issue.
How to Use Different Signatures in Outlook Desktop
# Outlook allows you to use different signatures in different emails. Here is how to use them in Outlook for # Windows and Mac.
Top 7 Ways to Fix Startup Programs Not Launching on Windows 10
# Startup # programs not launching on # Windows 10? Check out this # troubleshooting guide on how to remedy that.
Did You Know
YouTube is the second largest search engine. Google takes the first spot.
Как бороться с OutOfMemoryError на практике, или ох уж мне эти базы данных
Предыстория
Для начала нужно понять, как возникает OOM. Кому-то это может быть ещё неизвестно.
Представьте себе, что есть какой-то верхний предел занимаемой оперативки для приложения. Пусть это будет гигабайт ОЗУ.
Само по себе возникновение OOM в каком-то из потоков ещё не означает, что именно этот поток «выжрал» всю свободную память, да и вообще не означает, что именно тот кусок кода, который привёл к OOM, виноват в этом.
Вполне нормальна ситуация, когда какой-то поток чем-то занимался, поедая память, «дозанимался» этим до состояния «ещё немного, и я лопну», и завершил выполнение, приостановившись. А в это время какой-то другой поток решил запросить для своей маленькой работы ещё немного памяти, сборщик мусора попыжылся, конечно, но мусора уже в памяти не нашёл. В этом случае как раз и возникает OOM, не связанный с источником проблемы, когда стектрейс покажет совсем не того виновника падения приложения.
Есть и другой вариант. Около недели я исследовал, как улучшить жизнь парочки наших приложений, чтобы они перестали себя нестабильно вести. И ещё недельку-две потратил на то, чтобы привести их в порядок. В общей сложности пара недель времени, которые растянулись на полтора месяца, ведь занимался я не только этими проблемами.
Из найденного: сторонняя библиотека, и, конечно же, некоторые неучтённые вещи в вызовах хранимых процедур.
В одном приложении симптомы были следующие: в зависимости от нагрузки на сервис, оно могло упасть через сутки, а могло через двое. Если помониторить состояние памяти, то было видно, что приложение постепенно набирало «размер», и в определённый момент просто ложилось.
С другим приложением несколько интереснее. Оно может вести себя хорошо длительный срок, а могло перестать отвечать минут через 10 после перезагрузки, или вдруг внезапно упасть, сожрав всю свободную память (это я уже сейчас вижу, наблюдая за ним). А после обновления версии, когда была изменена и версия Tomcat с 7й до 8й, и JRE, оно вдруг в одну из пятниц (проработав вменяемо до этого ни много ни мало — 2 недели) начало творить такие вещи, что стыдно признаваться в этом. 🙂
В обоих историях очень полезны оказались дампы, благодаря им удалось отыскать все причины падений, подружившись с такими инструментами, как JVisualVM (буду называть его JVVM), Eclipse Memory Analyzing Tool (MAT) и языком OQL (может быть я не умею его правильно готовить в MAT, но мне оказалось легче подружиться с реализацией OQL именно в JVVM).
Ещё вам понадобится свободная оперативка для того, чтобы было куда загружать дампы. Её объём должен быть соизмерим с размером открываемого дампа.
Начало
Итак, начну потихоньку раскрывать карты, и начну именно с JVVM.
Этот инструмент в соединении с jstatd и jmx позволяет удалённо наблюдать за жизнью приложения на сервере: Heap, процессор, PermGen, количество потоков и классов, активность потоков, позволяет проводить профилирование.
Также JVVM расширяем, и я не преминул воспользоваться этой возможностью, установив некоторые плагины, которые позволили куда больше вещей, например, следить и взаимодействать с MBean’ами, наблюдать за деталями хипа, вести длительное наблюдение за приложением, держа в «голове» куда больший период метрик, чем предоставляемый вкладкой Monitor час.
Вот так выглядит набор установленных плагинов.
Visual GC (VGC) позволяет видеть метрики, связанные с хипом.
Вот два скриншота вкладки VGC, которые показывают, как ведут себя два разных приложения.
Слева Вы можете увидеть такие разделы хипа, как Perm Gen, Old Gen, Survivor 0, Survivor 1, и Eden Space.
Все эти составляющие — участки в оперативке, в которую и складываются объекты.
PermGen — Permanent Generation — область памяти в JVM, предназначенная для хранения описания классов Java и некоторых дополнительных данных.
Old Gen — это область памяти для достаточно старых объектов, которые пережили несколько перекладываний с места на место в Survivor-областях, и в момент какого-то очередного переливания попадают в область «старых» объектов.
Survivor 0 и 1 — это области, в которые попадают объекты, которые после создания объекта в Eden Space пережили его чистку, то есть не стали мусором на момент, когда Eden Space начал чиститься Garbage Collector’ом (GC). При каждом запуске чистки Eden Space объекты из активного в текущий момент Survivor’а перекладываются в пассивный, плюс добавляются новые, и после этого Survivor’ы меняются статусами, пассивный становится активным, а активный — пассивным.
Eden Space — область памяти, в которой новые объекты порождаются. При нехватке памяти в этой области запускается цикл GC.
Перейдём ко второму приложению:
В нём Eden напоминает мне какой-то уровень из Mortal Kombat, арену с шипами. Была такая, кажется… А График GC — шипы из NFS Hot Pursuit, вот те вот, плоские ещё.
Числа справа от названий областей указывают:
1) что Eden имеет размер в 50 мегабайт, и то, что нарисовано в конце графика, последнее из значений на текущий момент — занято 25 мегабайт. Всего он может вырости до 546 мегабайт.
2) что Old может вырости до 1,333 гига, сейчас занимает 405 МБ, и забит на 145,5 МБ.
Так же для Survivor-областей и Perm Gen.
Для сравнения — вот Вам Tracer-график за 75 часов работы второго приложения, думаю, кое-какие выводы вы сможете сделать из него. Например, что активная фаза у этого приложения — с 8:30 до 17:30 в рабочие дни, и что даже на выходных оно тоже работает 🙂
Если вы вдруг увидели в своём приложении, что Old-область заполнена — попробуйте просто подождать, когда она переполнится, скорее всего она заполнена уже мусором.
Мусор — это объекты, на которые нет активных ссылок из других объектов, или целые комплексы таких объектов (например, какое-то «облако» взаимосвязанных оъектов может стать мусором, если набор ссылок указывает только на объекты внутри этого «облака», и ни на один объект в этом «облаке» ничто не ссылается «снаружи»).
Это был краткий пересказ того, что я узнал про структуру хипа за время, пока гуглил.
Предпосылки
Итак, случилось сразу две вещи:
1) после перехода на более новые библиотеки/томкеты/джавы в одну из пятниц приложение, которое я уже долгое время веду, вдруг стало вести себя из рук вон плохо спустя две недели после выставления.
2) мне на рефакторинг отдали проект, который тоже вёл себя до некоторого времени не очень хорошо.
Я уже не помню, в каком точно порядке произошли эти события, но после «чёрной пятницы» я решил наконец-то разобраться с дампами памяти детальнее, чтобы это более не было для меня чёрным ящиком. Предупреждаю, что какие-то детали я мог уже запамятовать.
По первому случаю симптомы были такие: все потоки, отвественные за обработку запросов, выжраны, на базу данных открыто всего 11 соединений, и те не сказать, что используются, база говорила, что они в состоянии recv sleep, то есть ожидают, когда же их начнут использовать.
После перезагрузки приложение оживало, но прожить могло недолго, вечером той же пятницы жило дольше всего, но уже после окончания рабочего дня таки снова свалилось. Картина всегда была одинаковой: 11 соединений к базе, и лишь один, вроде бы, что-то делает.
Память, кстати, была на минимуме. Сказать, что OOM привёл меня к поиску причин, не могу, однако полученные знания при поиске причин позволили начать активную борьбу с OOM.
Когда я открыл дамп в JVVM, из него было сложно что-либо понять.
Подсознание подсказывало, что причина где-то в работе с базой.
Поиск среди классов сказал мне, что в памяти аж 29 DataSource, хотя должно быть всего 7.
Это и дало мне точку, от которой можно было бы оттолкнуться, начать распутывать клубок.
Сидеть переклацывать в просмотровщике все эти объекты было некогда, и моё внимание наконец-то привлекла вкладка OQL Console, я подумал, что вот он, момент истины — я или начну использовать её на полную катушку, или так и забью на всё это.
Прежде, чем начать, конечно же был задан вопрос гуглу, и он любезно предоставил шпаргалку (cheat sheet) по использованию OQL в JVVM: http://visualvm.java.net/oqlhelp.html
Сначала обилие сжатой информации привело меня в уныние, но после применения гугл-фу на свет таки появился вот такой OQL-запрос:
Это уже исправленная и дополненная, финальная версия этого запроса 🙂
Результат можно увидеть на скриншоте:
После нажатия на BasicDataSource#7 мы попадаем на нужный объект во вкладке Instances:
Через некоторое время до меня дошло, что есть одно несхождение с конфигурацией, указанной в теге Resource в томкете, в файле /conf/context.xml. Ведь в дампе параметр maxTotal имеет значение 8, в то время, как мы указывали maxActive равным 20…
Тут-то до меня и начало доходить, что приложение жило с неправильной конфигурацией пула соединений все эти две недели!
Для краткости напишу тут, что в случае, если вы используете Tomcat и в качестве пула соединений — DBCP, то в 7м томкете используется DBCP версии 1.4, а в 8м томкете — уже DBCP 2.0, в котором, как я потом выяснил, решили переименовать некоторые параметры! А про maxTotal вообще на главной странице сайта написано 🙂
http://commons.apache.org/proper/commons-dbcp/
«Users should also be aware that some configuration options (e.g. maxActive to maxTotal) have been renamed to align them with the new names used by Commons Pool 2.»
Причины
Обозвал их по всякому, успокоился, и решил разобраться.
Как оказалось, класс BasicDataSourceFactory просто напросто получает этот самый Resource, смотрит, есть ли нужные ему параметры, и забирает их в порождаемый объект BasicDataSource, молча игнорируя напрочь всё, что его не интересует.
Так и получилось, что они переименовали самые весёлые параметры, maxActive => maxTotal, maxWait => maxWaitMillis, removeAbandoned => removeAbandonedOnBorrow & removeAbandonedOnMaintenance.
По умолчанию maxTotal, как и ранее, равен 8; removeAbandonedOnBorrow, removeAbandonedOnMaintenance = false, maxWaitMillis устанавливается в значение «ждать вечно».
Получилось, что пул оказался сконфигурирован с минимальным количеством соединений; в случае, если заканчиваются свободные соединения — приложение молча ждёт, когда они освободятся; и добивает всё молчанка в логах по поводу «заброшенных» соединений — то, что могло бы сразу показать, в каком именно месте программист мудак код хватает соединение, но не отдаёт его обратно по окончанию своей работы.
Это сейчас вся мозаика сложилась быстро, а добывались эти знания дольше.
«Так быть не должно», решил я, и запилил патчик (https://issues.apache.org/jira/browse/DBCP-435, выразился в http://svn.apache.org/viewvc/commons/proper/dbcp/tags/DBCP_2_1/src/main/java/org/apache/commons/dbcp2/BasicDataSourceFactory.java?view=markup ), патч был принят и вошёл в версию DBCP 2.1. Когда и если Tomcat 8 обновит версию DBCP до 2.1+, думаю, что админам откроются многие тайны про их конфигурации Resource 🙂
По поводу этого происшествия мне лишь осталось рассказать ещё одну деталь — какого чёрта в дампе было аж 29 DataSource’ов вместо всего 7 штук. Разгадка кроется в банальной арифметике, 7*4=28 +1=29.
На каждую подпапку внутри папки /webapps поднимается своя копия /conf/context.xml, а значит то количество Resource, которые там есть, следует умножать на количество приложений, чтобы получить общее количество пулов, поднятых в памяти томкета. На вопрос «что в этом случае делать?» ответ будет таким: нужно вынести все объявления Resource из /conf/context.xml в файл /conf/server.xml, внутрь тега GlobalNamingResources. Там Вы можете найти один, имеющийся по умолчанию, Resource name=«UserDatabase», вот под ним и размещайте свои пулы. Далее необходимо воспользоваться тегом ResourceLink, его желательно поместить в приложение, в проекте, внутрь файла /META-INF/context.xml — это так называемый «per-app context», то есть контекст, который содержит объявления компонентов, которые будут доступны только для разворачиваемого приложения. У ResourceLink параметры name и global могут содержать одинаковые значения.
Для примера:
После этого всё стало ясно: 11 соединений было потому, что в одном, активном DataSource было съедено 8 соединений (maxTotal = 8), и ещё по minIdle=1 в трёх других неиспользуемых DataSource-копиях.
В ту пятницу мы откатились на Tomcat 7, который лежал рядышком, и ждал, когда от него избавятся, это дало время спокойно во всём разобраться.
Плюс позже, уже на TC7, обнаружилась утечка соединений, всё благодаря removeAbandoned+logAbandoned. DBCP радостно сообщил в логфайл catalina.log о том, что
Вот этот вот плохойПлохойМетод имеет в сигнатуре Connection con, но внутри была конструкция «con = getConnection();», которая и стала камнем преткновения. СуперКласс вызывается редко, поэтому на него и не обращали внимания так долго. Плюс к этому, вызовы происходили, я так понимаю, не во время рабочего дня, так что даже если что-то и подвисало, то никому уже не было дела до этого. А в ТуСамуюПятницу просто звёзды сошлись, начальнику департамента заказчика понадобилось посмотреть кое-что 🙂
Приложение №2
Что же касается «события №2» — мне отдали приложение на рефакторинг, и оно на серверах тут же вздумало упасть.
Дампы попали уже ко мне, и я решил попробовать поковырять и их тоже.
Открыл дамп в JVVM, и «чё-то приуныл»:
Что можно понять из Object[], да ещё и в таком количестве?
( Опытный человек, конечно же, увидел уже причину, правда? 🙂 )
Так у меня зародилась мысль «ну неужели никто ранее не занимался этим, ведь наверняка уже есть готовый инструмент!». Так я наткнулся на этот вопрос на StackOverflow: http://stackoverflow.com/questions/2064427/recommendations-for-a-heap-analysis-tool-for-java.
Посмотрев предложенные варианты, я решил остановиться на MAT, надо было попробовать хоть что-то, а это открытый проект, да ещё и с куда бОльшим количеством голосов, чем у остальных пунктов.
Eclipse Memory Analyzing Tool
Итак, MAT.
Рекомендую скачивать последнюю версию Eclipse, и устанавливать MAT туда, потому как самостоятельная версия MAT ведёт себя плохо, там какая-то чертовщина с диалогами, в них не видно содержимого в полях. Быть может кто-то подскажет в комментариях, чего ему не хватает, но я решил проблему, установив MAT в Eclipse.
Открыв дамп в MAT я запросил выполнение Leak Suspects Report.
Удивлению не было предела, честно говоря.
1.2 гига весят соединения в базу.
Каждое соединение весит от 17 до 81 мегабайта.
Ну и ещё «немного» сам пул.
Визуализировать проблему помог отчёт Dominator Tree:
Причиной всех падений оказались километры SQLWarning’ов, база настойчиво пыталась дать понять, что «010SK: Database cannot set connection option SET_READONLY_TRUE.», а пул соединений BoneCP не вычищает SQLWarning’и после освобождения и возврата соединений в пул (может быть это где-то можно сконфигурировать? Подскажите, если кто знает).
Гугл сказал, что такая проблема с Sybase ASE известна ещё с 2004 года: https://forum.hibernate.org/viewtopic.php?f=1&t=932731
Если вкратце, то «Sybase ASE doesn’t require any optimizations, therefore setReadOnly() produces a SQLWarning.», и указанные решения всё ещё работают.
Однако это не совсем решение проблемы, потому как решение проблемы — это когда при возврате соединения в пул все уведомления базы очищаются в силу того, что они уже никогда никому не понадобятся.
И DBCP таки умеет делать это: http://svn.apache.org/viewvc/commons/proper/dbcp/tags/DBCP_1_4/src/java/org/apache/commons/dbcp/PoolableConnectionFactory.java?view=markup, метод passivateObject(Object obj), в строке 687 можно увидеть conn.clearWarnings();, этот вызов и спасает от километров SQLWarning’ов в памяти.
Об этом я узнал из тикета: https://issues.apache.org/jira/browse/DBCP-102
Также мне подсказали про вот такой тикет в багтрекере: https://issues.apache.org/jira/browse/DBCP-234, но он касается уже версии DBCP 2.0.
В итоге я перевёл приложение на DBCP (пусть и версии 1.4). Пусть нагрузка на сервис и немаленькая (от 800 до 2к запросов в минуту), но всё же приложение ведёт себя хорошо, а это главное. И правильно сделал, потому как BoneCP уже пять месяцев не поддерживается, правда, ему на смену пришёл HikariCP. Нужно будет посмотреть, как дела в его исходниках…
Сражаемся с OOM
Впечатлившись тем, как MAT мне всё разложил по полочкам, я решил не забрасывать этот действенный инструмент, и позже он мне пригодился, потому как в первом приложении ещё остались всяческие «неучтёнки» — неучтённые вещи в коде приложения или коде хранимых процедур, которые иногда приводят к тому, что приложение склеивает ласты. Я их отлавливаю до сих пор.
Вооружившись обоими инструментами, я принялся ковырять каждый присланный дамп в поисках причин падения по OOM.
Как правило все OOM приводили меня к TaskThread.
И если нажать на надпись See stacktrace, то да, это будет как раз банальный случай, когда какой-то поток вдруг внезапно упал при попытке отмаршалить результат своей работы.
Однако здесь ничто не указывает на причину возникновения OOM, здесь лишь результат. Найти причину мне пока-что, в силу незнания всей магии OQL в MAT, помогает именно JVVM.
Загружаем дамп там, и пытаемся отыскать причину!
Искать мне следует, конечно же, именно вещи, связанные с базой данных, а посему попробуем сначала посмотреть, есть ли в памяти Statement’ы.
Два SybCallableStatement, и один SybPreparedStatement.
Думаю, что дело усложнится, если Statement’ов будет куда больше, но немного подрихтовав один из следующих запросов, указав в where нужные условия, думаю, всё у Вас получится. Плюс, конечно же, стоит хорошенько посмотреть в MAT, что за результаты пытается отмаршалить поток, какой объект, и станет понятнее, какой именно из Statement’ов необходимо искать.
Не то, это «внутренние» вызовы.
А вот и дичь!
Для чистоты эксперимента можно кинуть такой же запрос в любимой БД-IDE, и он будет очень долго отрабатывать, а если покопаться в недрах хранимки, то будет понятно, что там просто из базы, которая нам не принадлежит, выбирается 2 миллиона строк по такому запросу с такими параметрами. Эти два миллиона даже влазят в память приложения, но вот попытка отмаршалить результат становится фатальной для приложения. Такое себе харакири. 🙂
При этом GC старательно убирает все улики, но не спасло его это, всё же источник остался в памяти, и он будет наказан.
Почему-то после всего этого рассказа почувствовал себя тем ещё неудачником.
Прощание
Вот и закончилось моё повествование, надеюсь, Вам понравилось 🙂
Хотел бы выразить благодарность своему начальнику, он дал мне время во всём этом разобраться. Считаю эти новые знания очень полезными.
Спасибо девушкам из Scorini за неизменно вкусный кофе, но они не прочтут этих слов благодарности — я даже сомневаюсь, что они знают о существовании Хабрахабра 🙂
Хотелось бы увидеть в комментариях ещё больше полезной инфы и дополнений, буду очень благодарен.
Думаю, самое время почитать документацию к MAT…
UPD2 (2015-10-28) | Случай номер два три
(Было принято решение дописать это сюда как апдейт, а не пилить новую статью о том же самом):
Ещё один интересный случай, но уже с Оракловой базой.
Один из проектов использует фичу с XML, проводит поиски по содержимому сохранённого XML-документа. В общем, этот проект иногда давал о себе знать тем, что вдруг внезапно один из инстансов переставал подавать признаки жизни.
Почуяв «хороший» случай потренироваться на кошках, я решил посмотреть его дампы памяти.
Первое, что я увидел, было «у вас тут много коннектов в памяти осталось». 21к. И какой-то интересный oracle.xdb.XMLType тоже давал жару. «Но это же Оракл!», вертелось у меня в голове. Забегая вперёд скажу что таки да, он виноват.
Итак, видим кучу T4CConnection, которые лежат в HashMap$Entry. Обратил внимание сразу, что вроде бы и SoftHashMap, что, вроде как, должно означать, что оно не должно вырастать до таких размеров. Но результат видите и сами — 50-60 килобайт в коннекте, и их реально МНОГО.
Посмотрев, что собой представляют HashMap$Entry — увидел, что примерно картина одинакова, всё связано с SoftHashMap, с Оракловыми коннектами.
Что, собственно, подтверждалось такой картинкой. HashMap$Entry было просто море, и они более-менее сакуммулировались внутри oracle.xdb.SoftHashMap.
В следующем дампе картина была примерно такой же. По Dominator Tree было видно, что внутри каждого Entry находится тяжёлый такой BinXmlProcessorImpl.
-=-=-
Если учесть, что я в тот момент был не силён в том, что такое xdb, и как он связан с XML, то, несколько растерявшись, я решил, что надо бы погуглить, быть может кто-то уже в курсе, что со всем этим нужно делать. И чутьё не обмануло, по запросу «oracle.xdb.SoftHashMap T4CConnection» нашлось
раз piotr.bzdyl.net/2014/07/memory-leak-in-oracle-softhashmap.html
и два leakfromjavaheap.blogspot.com/2014/02/memory-leak-detection-in-real-life.html
Утвердившись, что тут всё-таки косяк у Оракла, дело оставалось за малым.
Попросил администратора БД посмотреть информацию по обнаруженной проблеме: