java .lang.OutOfMemoryError: невозможно создать новую ошибку собственного потока, используя ChromeDriver и Chrome через Selenium при загрузке Spring - PullRequest
1 голос
/ 20 февраля 2020

У нас есть веб-приложение на основе селена, разработанное с использованием весенней загрузки. Сервер расположен как виртуальный экземпляр на облачном сервере Google.

У нас есть механизм потоковой базы, использующий Executor . Используя селен, мы открываем браузер chrome (без головы) для выполнения операции и для каждой операции создаем новый поток.

После ошибки outOfMemory, если мы перезапускаем экземпляр облака, то в течение 1 часа он снова прерывается с та же ошибка.

Ниже приведен фрагмент, который мы использовали для создания нового экземпляра службы исполнителя для каждого запроса.

executorService = Executors.newFixedThreadPool(1);
Future<Object> futureDetails = executorService.submit(new Callable<Object>() {

        @Override
        public Object call() throws Exception {

            Object response = client.getDetails(number);

            return response;
        }
    });

    executorService.shutdown();

У нас есть сервер (16 виртуальных ЦП, 64 ГБ памяти) конфигурация.

Ниже приведены подробные сведения о версии.

Spring Boot - 2.0.0.RELEASE

Selenium - 3.9.1

Linux - Debian 4.9.130-2 (2018-10-27) x86_64 GNU / Linux

Chrome Драйвер - 2.35.528139 (47ead77cb35ad2a9a83248b292151462a66cd881)

Google Chrome - 70,0 .3538.110

JDK - 1.8.0_232

Ниже приведен отчет о ресурсах с использованием: ulimit -a.

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 257648
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 10240
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 257648
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Кроме того, я проверил память с помощью: free -m

              total        used        free      shared  buff/cache   available
Mem:          64433        9479       54490         279         463       54132
Swap:             0           0           0

Ниже приведена трассировка стека ошибок:

org.springframe work.web.util.NestedServletException: ошибка отправки обработчика; вложенное исключение: java .lang.OutOfMemoryError: невозможно создать новый собственный поток в org.springframework.web.servlet.DispatcherServlet.doDispatch (DispatcherServlet. java: 1006) ~ [spring-web mvc -5.0.4 .RELEASE.jar! /: 5.0.4.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService (DispatcherServlet. java: 925) ~ [spring-web mvc -5.0.4.RELEASE.jar ! /: 5.0.4.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest (FrameworkServlet. java: 978) ~ [spring-web mvc -5.0.4.RELEASE.jar! /: 5.0 .4.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doPost (FrameworkServlet. java: 881) ~ [spring-web mvc -5.0.4.RELEASE.jar! /: 5.0.4.RELEASE ] в javax.servlet.http.HttpServlet.service (HttpServlet. java: 661) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в org.springframework.web.servlet.FrameworkServlet. сервис (FrameworkServlet. java: 855) ~ [spring-web mvc -5.0.4.RELEASE.jar! /: 5.0.4.RELEASE] по адресу javax.servlet.http.HttpServlet.service (HttpServlet. * 1063) *: 742) [tomcat-embe d-core-8.5.28.jar! /: 8.5.28] в орг. apache .catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain. java: 231) [tomcat-embed-core-8.5.28. jar! /: 8.5.28] at org. apache .catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain. java: 166) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в орг. apache .tomcat.websocket.server.WsFilter.doFilter (WsFilter. java: 52) [tomcat-embed-websocket-8.5.28.jar! /: 8.5.28] в орг. apache .catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain. java: 193) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в орг. apache .catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain. java: 166) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy. java: 320 ) [spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] в org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke (FilterSecurityInterceptor. java: 127) [ SPRI ng-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter (FilterSecurityInterceptor. java: 91) [spring- security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy. java: 334) [spring-security-web- 5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] в org.springframework.security.web.access.ExceptionTranslationFilter.doFilter (ExceptionTranslationFilter. java: 119) [spring-security-web-5.0.3. RELEASE.jar! /: 5.0.3.RELEASE] в орг. springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy. java: 334) [spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] в org.springframework.security. web.session.SessionManagementFilter.doFilter (SessionManagementFilter. java: 137) [spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy. java: 334) [spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] в org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter ( AnonymousAuthenticationFilter. java: 111) [spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] на org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy. * 1083) *: 334) [spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] по адресу org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter (SecurityContextHolderAwareRequestFilter.) 170 *. 1084 [спр ing-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy. java: 334) [spring-security- web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] по адресу org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter (RequestCacheAwareFilter. java: 63) [spring-security-web-5.0. 3.RELEASE.jar! /: 5.0.3.RELEASE] в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy. java: 334) [spring-security-web-5.0.3.RELEASE. jar! /: 5.0.3.RELEASE] at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter (OAuth2AuthenticationProcessingFilter. java: 176) [spring-security-oauth2-2.2.1j.AREASE! /: na] at org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy. java: 334) [spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] в org.springframework.security.web.authentication.logout.LogoutFilter. doFilter (LogoutFilter. java: 116) [spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] по адресу org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy. java: 334) [spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] по адресу org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal (HeaderWriterFilter. java: 66) [spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] по адресу org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter. java: 107) [spring-web -5.0.4.RELEASE.jar! /: 5.0.4.RELEASE] в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy. java: 334) [spring-security-web-5.0.3 .RELEASE.jar! /: 5.0.3.RELEASE] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter (SecurityContextPersistenceFilter. java: 105) [spring-security-web-5.0.3.RELEASE.jar ! /: 5.0.3.RELEASE] at org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (F ilterChainProxy. java: 334) [spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] по адресу org.springframework.security.web.context.request.asyn c .WebAsyncManagerIntegrationFilter .doFilterInternal (WebAsyncManagerIntegrationFilter. java: 56) [spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] в org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequest) 1099 *: 107) [spring-web-5.0.4.RELEASE.jar! /: 5.0.4.RELEASE] в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy. java: 334) [ spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] в org.springframework.security.web.FilterChainProxy.doFilterInternal (FilterChainProxy. java: 215) [spring-security-web- 5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] в org.springframework.security.web.FilterChainProxy.doFilter (FilterChainProxy. java: 178) [spring-security-web-5.0.3.RELEASE.jar! /: 5.0.3.RELEASE] по адресу org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate (DelegatingFilterProxy. java: 357) [spring-web-5.0.4.RELEASE.jar! /: 5.0.4.RELEASE] по адресу org.springframework.web.filter.DelegatingFilterProxy.doFilter (DelegatingFilterProxy. java: 270) [spring-web-5.0.4 .RELEASE.jar! /: 5.0.4.RELEASE] at org. apache .catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain. java: 193) [tomcat-embed-core-8.5.28.jar! / : 8.5.28] at org. apache .catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain. java: 166) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в орг. springframework.web.filter.RequestContextFilter.doFilterInternal (RequestContextFilter. java: 99) [spring-web-5.0.4.RELEASE.jar! /: 5.0.4.RELEASE] в org.springframework.web.filter.OncePerRequestFilter. doFilter (OncePerRequestFilter. java: 107) [spring-web-5.0.4.RELEASE.jar! /: 5.0.4.RELEASE] в орг. apache .catalina.core.ApplicationFilterChain.internalDo Filter (ApplicationFilterChain. java: 193) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] at org. apache .catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain. java: 166) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal (HttpPutFormContentFilter. java: 109) [spring-web-5.0.4 .RELEASE.jar! /: 5.0.4.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter. java: 107) [spring-web-5.0.4.RELEASE.jar! /: 5.0 .4.RELEASE] at org. apache .catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain. java: 193) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в орг. apache .catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain. java: 166) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в org.springframework.web.filter.HiddenHttpMethodFilter. doFilterInternal (HiddenHttpMethodFilter. java: 81) [spring-web-5.0.4.RELEASE.jar! /: 5.0.4.RELEASE] в org.springframework.web.filter.OncePerReque stFilter.doFilter (OncePerRequestFilter. java: 107) [spring-web-5.0.4.RELEASE.jar! /: 5.0.4.RELEASE] at org. apache .catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain. java: 193) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в орг. apache .catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain. java: 166) [tomcat -embed-core-8.5.28.jar! /: 8.5.28] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal (CharacterEncodingFilter. java: 200) [spring-web-5.0.4.RELEASE.jar ! /: 5.0.4.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter. java: 107) [spring-web-5.0.4.RELEASE.jar! /: 5.0.4.RELEASE ] в орг. apache .catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain. java: 193) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в орг. apache. catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain. java: 193) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в орг. apache .catalina.core.Applicat ionFilterChain.doFilter (ApplicationFilterChain. java: 166) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] at org. apache .catalina.core.StandardWrapperValve.invoke (StandardWrapperValve. java: 199) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в орг. apache .catalina.core.StandardContextValve.invoke (StandardContextValve. java: 96) [tomcat-embed -core-8.5.28.jar! /: 8.5.28] at org. apache .catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase. java: 496) [tomcat-embed-core-8.5.28.jar ! /: 8.5.28] в орг. apache .catalina.core.StandardHostValve.invoke (StandardHostValve. java: 140) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в org. apache .catalina.valves.ErrorReportValve.invoke (ErrorReportValve. java: 81) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в org. apache .catalina. core.StandardEngineValve.invoke (StandardEngineValve. java: 87) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в орг. apache .catalina.connector.CoyoteAdapter.service (CoyoteAdapter. java: 342) [tomcat -embed-core-8.5.28.jar! /: 8.5.28] в орг. apache .coyote.http11.Http11Processor.service (Http11Processor. java: 803) [tomcat-embed-core-8.5.28 .jar! /: 8.5.28] at org. apache .coyote.AbstractProcessorLight.process (AbstractProcessorLight. java: 66) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в org. apache .coyote.AbstractProtocol $ ConnectionHandler.process (AbstractProtocol. java: 790) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в org. apache .tomcat. util. net .NioEndpoint $ SocketProcessor.doRun (NioEndpoint. java: 1459) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в орг. apache .tomcat.util. net .SocketProcessorBase.run (SocketProcessorBase. java: 49) [tomcat-embed-core-8.5.28.jar! /: 8.5.28] в java .util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor. java: 1149) [na: 1.8.0_241] в java .util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor. java: 624) [na: 1.8.0_241] at org. apache .tomcat.util.threads.TaskThread $ WrappingRunnable.run (TaskThread. java: 61) [tomcat-embed-core-8.5.28.jar! /: 8.5 .28] at java .lang.Thread.run (Thread. java: 748) [na: 1.8.0_241] Причина: java .lang.OutOfMemoryError: невозможно создать новый собственный поток

Пожалуйста, помогите мне понять проблему и root причину этой проблемы. Было бы лучше, если бы вы также могли предложить решение.

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

Ответы [ 3 ]

2 голосов
/ 20 февраля 2020

Это сообщение об ошибке ...

java.lang.OutOfMemoryError: unable to create new native thread

... означает, что JVM не удалось создать какой-либо новый собственный поток, так как ваша система запустила OutOfMemory


OutOfMemoryError

Недостаточно памяти Сообщения об ошибках могут появляться при попытке запуска новых программ или при использовании уже запущенных программ, даже если у вас еще много память подкачки доступна. Когда вы запускаете программу java или java, выделяет часть памяти для JVM. JVM делит эту память на две части. Один из них - Память стека , а другой - Память кучи . Память стека используется для выполнения методов, в то время как Память кучи используется для хранения объектов. Когда куча заполняется, JVM выдает java.lang.OutOfMemoryError.


java .lang.OutOfMemoryError

java .lang.OutOfMemoryError выбрасывается, когда Куча памяти заполнена, а JVM не может выделить память для новых объектов. Поскольку объекты, которые вы создаете в Java, хранятся в Heap Memory , поэтому, когда объекты больше не нужны, они должны быть удалены из памяти. Сборщик мусора автоматически удаляет ненужные объекты из Кучи памяти . Если ваши объекты имеют живые ссылки, сборщик мусора не удаляет их. Он удаляет только те объекты, которые не имеют живых ссылок. в этом процессе, если в какой-то момент времени не останется места для новых объектов в памяти кучи, JVM сгенерирует java.lang.OutOfMemoryError.


Этот сценарий использования

Согласно вашему коду В испытаниях вы реализовали многопоточность с использованием ThreadPoolExecutor для создания и использования потока для каждого запроса при открытии контекста просмотра.


Многопоточность с использованием Selenium

Как вы упомянули, в течение 1 часа происходит сбой agian с той же ошибкой, я подозреваю, что это связано с тем, что WebDriver не является потокобезопасным . Тем не менее, если вы можете сериализовать доступ к базовому экземпляру драйвера, вы можете поделиться ссылкой более чем в одном потоке. Это не рекомендуется. Но вы всегда можете создать один экземпляр WebDriver для каждого потока.

В идеале проблема thread-safety не в вашем коде, а в реальных привязках браузера. Все они предполагают, что будет только одна команда за раз (например, как настоящий пользователь). Но с другой стороны, вы всегда можете создать один экземпляр WebDriver для каждого потока, который будет запускать несколько вкладок просмотра / windows. До этого момента кажется, что ваша программа идеальна.

Теперь разные потоков могут быть запущены на одном Webdriver , но тогда результаты тестов не будут такими вы ожидаете. Причина в том, что когда вы используете многопоточность для запуска разных тестов на разных вкладках / windows требуется немного кодирования безопасности потока, иначе вы будете выполнять такие действия, как click() или send_keys() go к открытой вкладке / окну, которое в настоящее время имеет focus независимо от того, какой поток вы ожидаете запустить. Это по сути означает, что все тесты будут выполняться одновременно на одной вкладке / окне, в котором есть focus , но not на предполагаемой вкладке / окне.


Дополнительные замечания

Однако другой проблемой является несовместимость между версиями двоичных файлов, которые вы используете следующим образом:

  • Вы используете chromedriver = 2,35
  • В заметках о выпуске chromedriver = 2,35 четко упоминается следующее:

Поддержка Chrome v62 -64

  • Вы используете chrome = 70.0
  • Примечания к выпуску ChromeDriver vv2.44 ясно упоминает следующее:

Поддержка Chrome v69-71

  • Ваш Клиент Selenium версия 3.9.1 , что почти 2 лет старше.

Таким образом, существует явное несоответствие между Selenium Client v3.9.1 , ChromeDriver v2.35 и Chrome Браузер v70.0


Решение

Убедитесь, что:

  • JDK является повышен до текущих уровней JDK 8u241 .
  • Selenium обновлен до текущих уровней Версия 3.141.59 .
  • ChromeDriver обновлен до текущего ChromeDriver v80.0 уровень.
  • Chrome обновлен до текущего Chrome Версия 80.0 уровень. (согласно примечаниям к выпуску ChromeDriver v80.0 )
  • Если ваша базовая Веб-клиент версия устарела, затем удалите ее через Revo Uninstaller и установите последнюю версию GA и выпущенную версию Веб-клиент .
  • Возьмите Перезагрузку системы .
  • Всегда вызывать driver.quit() в tearDown(){} способ закрыть и уничтожить WebDriver и Веб-клиент изящно.

tl; dr

Как установить ограничение памяти для OOM Killer для chrome?

0 голосов
/ 25 февраля 2020

Я тоже столкнулся с этой проблемой. Проблема заключалась в том, что если отправленный или выполненный поток пула обращался за пределы пула к чему-то, что требует «слишком много» памяти. Если у вас есть поток, который осуществляет такой доступ, вы должны запустить его как поток REAL , а не как Runnable в пуле ExecutorService.

0 голосов
/ 20 февраля 2020

Объем оперативной памяти вашего сервера не имеет значения, если вы не выделите эту память для вашего java процесса.

Если вы запускаете приложение с помощью (любого варианта) команды java -jar, добавьте максимально допустимый параметр памяти -xmx (отметьте этот вопрос ). Если приложение запускается внутри Tomcat (или любого сервера приложений), вам необходимо увеличить максимально допустимое количество памяти (проверить его параметры и документы).

...