我们已经使用Spring Boot开发了基于 Selenium 的Web应用程序。该服务器位于Google云端服务器上,作为VM实例。
我们有一个使用执行器的线程基础机制。使用 Selenium ,我们打开一个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个vCPU,64 GB内存)服务器配置。
请在下面找到该版本的详细信息。
Spring 靴-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)
谷歌浏览器-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.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: unable to create new native thread at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1006) ~[spring-webmvc-5.0.4.RELEASE.jar!/:5.0.4.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.4.RELEASE.jar!/:5.0.4.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978) ~[spring-webmvc-5.0.4.RELEASE.jar!/:5.0.4.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:881) ~[spring-webmvc-5.0.4.RELEASE.jar!/:5.0.4.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.28.jar!/:8.5.28] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855) ~[spring-webmvc-5.0.4.RELEASE.jar!/:5.0.4.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.28.jar!/:8.5.28] at org.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] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.28.jar!/:8.5.28] 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] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320) [spring-security-web-5.0.3.RELEASE.jar!/:5.0.3.RELEASE] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) [spring-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] at 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.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119) [spring-security-web-5.0.3.RELEASE.jar!/:5.0.3.RELEASE] at 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.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) [spring-security-web-5.0.3.RELEASE.jar!/:5.0.3.RELEASE] at 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.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) [spring-security-web-5.0.3.RELEASE.jar!/:5.0.3.RELEASE] at 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.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) [spring-security-web-5.0.3.RELEASE.jar!/:5.0.3.RELEASE] at 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.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) [spring-security-web-5.0.3.RELEASE.jar!/:5.0.3.RELEASE] at 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.1.RELEASE.jar!/:na] at 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.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) [spring-security-web-5.0.3.RELEASE.jar!/:5.0.3.RELEASE] at 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.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) [spring-security-web-5.0.3.RELEASE.jar!/:5.0.3.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.4.RELEASE.jar!/:5.0.4.RELEASE] at 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(FilterChainProxy.java:334) [spring-security-web-5.0.3.RELEASE.jar!/:5.0.3.RELEASE] at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) [spring-security-web-5.0.3.RELEASE.jar!/:5.0.3.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.4.RELEASE.jar!/:5.0.4.RELEASE] at 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.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) [spring-security-web-5.0.3.RELEASE.jar!/:5.0.3.RELEASE] at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) [spring-security-web-5.0.3.RELEASE.jar!/:5.0.3.RELEASE] at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) [spring-web-5.0.4.RELEASE.jar!/:5.0.4.RELEASE] at 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] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [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] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.28.jar!/:8.5.28] at 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] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.28.jar!/:8.5.28] at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) [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] at org.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] 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.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] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) [tomcat-embed-core-8.5.28.jar!/:8.5.28] at org.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] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.28.jar!/:8.5.28] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.28.jar!/:8.5.28] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.28.jar!/:8.5.28] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.28.jar!/:8.5.28] at org.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] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.28.jar!/:8.5.28] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.28.jar!/:8.5.28] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.28.jar!/:8.5.28] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_241] at 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] Caused by: java.lang.OutOfMemoryError: unable to create new native thread
请帮助我了解问题和此问题的根本原因。如果您也可以提出解决方案,那将更好。
提前致谢。
最佳答案
此错误消息...
java.lang.OutOfMemoryError: unable to create new native thread
...暗示JVM无法在系统运行OutOfMemory时创建任何新的 native 线程
OutOfMemoryError
当您尝试启动新程序或尝试使用已运行的程序时,即使您仍然有足够的物理和页面文件存储空间,也会出现Out of Memory错误消息。当您运行Java程序或Java应用程序时,os会为JVM分配一些内存。 JVM将该内存分为两部分。一个是堆栈内存,另一个是堆内存。堆栈内存用于执行方法,而堆内存用于存储对象。当堆变满时,JVM会抛出
java.lang.OutOfMemoryError
。java.lang.OutOfMemoryError
当堆内存已满并且JVM无法将内存分配给新对象时,将抛出java.lang.OutOfMemoryError。由于您用Java创建的对象存储在堆内存中,因此,当不再需要这些对象时,必须将其从内存中删除。垃圾收集器会自动从堆内存中删除不需要的对象。如果您的对象具有实时引用,则垃圾收集器不会删除它们。它仅删除那些没有实时引用的对象。在此过程中,如果在任何时间点堆内存中没有剩余空间供新对象使用,则JVM将抛出
java.lang.OutOfMemoryError
。这个用例
根据您的代码试用,您已经使用ThreadPoolExecutor实现了多线程,从而在打开google-chrome-headless浏览上下文时为每个请求创建和使用线程。
使用Selenium的多线程
正如您所提到的,在1小时内它以相同的错误破坏了agian,我怀疑这是由于WebDriver is not thread-safe造成的。话虽如此,如果您可以序列化对底层驱动程序实例的访问,则可以在多个线程中共享一个引用。这是不可取的。但是,您始终可以为每个线程实例化一个WebDriver实例。
理想情况下,线程安全性的问题不在您的代码中,而是在实际的浏览器绑定(bind)中。他们都假设一次只能有一个命令(例如,像真实用户一样)。但是另一方面,您始终可以为每个线程实例化一个WebDriver实例,这将启动多个浏览选项卡/窗口。到此为止,您的程序似乎是完美的。
现在,可以在同一Webdriver上运行不同的线程,但是测试结果将不是您期望的。背后的原因是,当您使用多线程在不同的选项卡/窗口上运行不同的测试时,需要一些线程安全编码,否则您将执行的操作(如
click()
或send_keys()
)将转到打开的选项卡/窗口,即当前具有焦点,无论您希望运行的线程如何。从本质上讲,这意味着所有测试将同时在目标选项卡/窗口上具有焦点但而不是的同一选项卡/窗口上同时运行。附加注意事项
但是,另一个问题是正在使用的二进制版本之间的不兼容,如下所示:
Supports Chrome v62-64
Supports Chrome v69-71
因此,Selenium Client v3.9.1,ChromeDriver v2.35和Chrome浏览器v70.0之间显然存在不匹配
解决方案
确保这件事:
driver.quit()
方法中调用tearDown(){}
以优雅地关闭和销毁WebDriver和Web Client实例。 tl;博士
How to set memory limit for OOM Killer for chrome?
关于java - java.lang.OutOfMemoryError : unable to create new native thread error using ChromeDriver and Chrome through Selenium in Spring boot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60318473/