[英]Raspberry PI 2 Java 8 JVM error
I am in the process of building a web app based on Java 1.8, spring, hibernate, mysql and using tomcat as web server. 我正在构建基于Java 1.8,spring,hibernate,mysql的Web应用程序,并使用tomcat作为Web服务器。 Right now my app is logging (@5 sec interval) the raspberry's system data like;
现在我的应用正在记录(每隔5秒)树莓的系统数据,例如: cpu temperature, cpu core voltage, used memory, free memory, memory buffers, etc. The problem is that from time to time the app is crashing because it's running out of memory and I can't identify the reason.
cpu温度,cpu核心电压,已用内存,可用内存,内存缓冲区等。问题是应用程序不时崩溃是因为它的内存不足,我无法确定原因。
First, on tomcat I had the following lines in tomcat's startup service : 首先,在tomcat上,tomcat的启动服务中包含以下几行:
Environment='CATALINA_OPTS=-Xms256M -Xmx512M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'
and it was crashing in about 8 hours after starting tomcat. 并且在启动tomcat之后约8小时内崩溃了。 I removed those lines and now it is crashing at about 2 days because it is out of memory.
我删除了这些行,现在由于内存不足,它在大约2天后崩溃了。 Today it was the first time when it crashed without those lines in starting script and my last line inserted in db was:
今天,这是它第一次崩溃,但启动脚本中没有这些行,而我在db中插入的最后一行是:
# id, cpuTemperature, cpuCoreVoltage, usedMemory, freeMemory, memoryBuffers, sdramCVoltage, sdramIVoltage, sdramPVoltage, createdAt, modifiedAt, createdBy, modifiedBy
'52414', '39', '1.3125', '958320640', '12447744', '92495872', '1.2', '1.2', '1.225', '2015-11-23 15:53:58', NULL, NULL, NULL
For this info I am using SystemInfo class from pi4j library. 对于此信息,我正在使用pi4j库中的SystemInfo类。 getMemoryUsed() is returning used memory in bits so after a simple math we obtain a used memory of 913.92 Mb.
getMemoryUsed()返回以位为单位的已用内存,因此在简单的数学运算之后,我们得到的已用内存为913.92 Mb。
When app start, it is consuming only 250 Mb ram and after 3 day is crashing the app beacause it's reaching the maximum memory of the raspberry pi. 启动应用程序时,它仅消耗250 Mb的内存,而3天后崩溃的原因是应用程序达到了树莓派的最大内存。
Spring App Config: Spring App Config:
@Configuration
@EnableWebMvc
@EnableScheduling
@ComponentScan({"ro.i2cWebAppController.app.controller","ro.i2cWebAppController.app.serv","ro.i2cWebAppController.app.schedule"})
@Import({SpringSecurityConfig.class})
@EnableJpaRepositories({"ro.i2cWebAppController.app.repo"})
public class AppConfig extends WebMvcConfigurerAdapter {
private static final Logger logger = Logger.getLogger(AppConfig.class);
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/res/**").addResourceLocations("/WEB-RES/");
registry.addResourceHandler("/**/**.ico").addResourceLocations("/WEB-RES/img/favicon.ico");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Bean
public ViewResolver viewResolver(ContentNegotiationManager manager) {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("views/");
resolver.setSuffix(".jsp");
return resolver;
}
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean sessionFactory() {
LocalContainerEntityManagerFactoryBean lcemfb = new LocalContainerEntityManagerFactoryBean();
HibernateJpaVendorAdapter hjva = new HibernateJpaVendorAdapter();
hjva.setShowSql(true);
//persistence unit
lcemfb.setDataSource(dataSource());
lcemfb.setJpaVendorAdapter(hjva);
lcemfb.setPackagesToScan("ro.i2cWebAppController.app.model");
lcemfb.setJpaPropertyMap(hibernateProperties());
return lcemfb;
}
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
if(isUnix()){
dataSource.setUrl("jdbc:mysql://localhost:3306/i2cwac?autoReconnect=true");
}else{
dataSource.setUrl("jdbc:mysql://192.168.1.30:3306/i2cwac?autoReconnect=true");
}
dataSource.setUsername("i2cwac");
dataSource.setPassword("Stefan1234");
dataSource.setInitialSize(5);
dataSource.setMaxTotal(20);
dataSource.setMaxIdle(10);
dataSource.setMinIdle(5);
dataSource.setMaxWaitMillis(2000);
return dataSource;
}
@Bean
@Autowired
public JpaTransactionManager transactionManager(EntityManagerFactory lcemfb) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(lcemfb);
return txManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
Map<String,String> hibernateProperties() {
Map<String,String> propMap = new HashMap<>();
propMap.put("hibernate.hbm2ddl.auto", "validate");
propMap.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
propMap.put("hibernate.globally_quoted_identifiers", "true");
propMap.put("hibernate.show_sql", "true");
return propMap;
}
@Bean
public Integer ambientTemperature(){
return new Integer(0);
}
@Bean
public SystemInformationService systemInformationService(){
return new SystemInformationServiceImpl();
}
@Bean
public Boolean isUnix(){
if(System.getProperty("os.name").toLowerCase().indexOf("win")>=0){
logger.info("isUnix : false because : " + System.getProperty("os.name"));
return false;
}else{
logger.info("isUnix : true because : " + System.getProperty("os.name"));
return true;
}
}
@Bean
public I2CBus i2CBus(){
I2CBus i2CBus = null;
if (isUnix()) {
int count = 0;
int maxTries = 10;
while (true) {
try {
i2CBus = I2CFactory.getInstance(I2CBus.BUS_1);
break;
} catch (IOException e) {
++count;
logger.error("I2CBUS try " + count);
if (count == maxTries) e.printStackTrace();
}
}
}
if (i2CBus == null){
logger.info("I2CBUS is NULL");
}else{
logger.info("Got I2CBUS " + i2CBus.toString());
}
return i2CBus;
}
}
Scheduler class: 调度程序类:
@Component
public class RaspberryPiScheduler {
@Autowired
SystemInformationService systemInformationService;
@Autowired
RaspberryPiDataService raspberryPiDataService;
@Autowired
Boolean isUnix;
private static final Logger logger = Logger.getLogger(RaspberryPiScheduler.class);
/**
* Scheduled method to write data from Raspberry Pi sensors
*/
@Scheduled(fixedDelay = 5000)
public void writeRaspberryPiData(){
logger.info("Insert raspberrypi stats");
if(isUnix){
try {
raspberryPiDataService.save(new RaspberryPiData(
systemInformationService.getCpuTemperature(),
systemInformationService.getCpuVoltage(),
systemInformationService.getMemoryUsed(),
systemInformationService.getMemoryFree(),
systemInformationService.getMemoryBuffers(),
systemInformationService.getMemoryVoltageSDRam_C(),
systemInformationService.getMemoryVoltageSDRam_I(),
systemInformationService.getMemoryVoltageSDRam_P()
));
} catch (Exception e) {
logger.error("writeRaspberryPiData error",e);
}
}
}
}
Base Repo: 基本回购:
@NoRepositoryBean
public interface BaseRepo<T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {
}
Right now I don't find the error in the log, but in the past it crashed with SIGILL error. 现在我在日志中找不到错误,但是在过去,它因SIGILL错误而崩溃。 I will edit this post after finding the log.
找到日志后,我将编辑此帖子。
I found the log with error from JVM: 我发现了来自JVM的错误日志:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGILL (0x4) at pc=0x741db028, pid=1918, tid=1620767840
#
# JRE version: Java(TM) SE Runtime Environment (8.0-b132) (build 1.8.0-b132)
# Java VM: Java HotSpot(TM) Server VM (25.0-b70 mixed mode linux-arm )
# Problematic frame:
# J 1635 C2 com.mysql.jdbc.ResultSetImpl.<init>(JJLcom/mysql/jdbc/MySQLConnection;Lcom/mysql/jdbc/StatementImpl;)V (314 bytes) @ 0x741db028 [0x741dae20+0x208]
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
#
--------------- T H R E A D ---------------
Current thread (0x63003c00): JavaThread "pool-2-thread-2" [_thread_in_Java, id=1967, stack(0x60960000,0x609b0000)]
siginfo:si_signo=SIGILL: si_errno=0, si_code=1 (ILL_ILLOPC), si_addr=0x741db028
Registers:
r0 = 0x71897568
r1 = 0x00000008
r2 = 0x00000000
r3 = 0x00000000
r4 = 0x62922d40
r5 = 0x00000368
r6 = 0x693d65e8
r7 = 0x62922d40
r8 = 0x73a51000
r9 = 0x66c13e30
r10 = 0x63003c00
fp = 0x693d65e8
r12 = 0x718974b8
sp = 0x609adfa0
lr = 0x73e74bb0
pc = 0x741db028
cpsr = 0x60000010
Top of Stack: (sp=0x609adfa0)
0x609adfa0: 6e614d79 3d74696d 00000007 00000000
0x609adfb0: 609ae008 73e74bb0 00000000 00000000
0x609adfc0: 693d65e8 00000000 00000000 00000000
0x609adfd0: 693d65e8 00000000 00000000 00000000
0x609adfe0: 00000000 718974b8 609adfe8 629d07b7
0x609adff0: 609ae028 629d4420 602ed004 629d0800
0x609ae000: 609adfcc 609ae010 609ae04c 73e74bb0
0x609ae010: 00000000 693d65e8 00000000 00000000
Instructions: (pc=0x741db028)
0x741db008: e5d45008 e59cb05c e5cc5044 f57ff05f
0x741db018: e59b4004 e1540007 1a00003a e3005368
0x741db028: e18b40d5 e59c605c e1cc40f8 f57ff05f
0x741db038: e5964004 e1540007 1a000036 e5964478
Register to memory mapping:
r0 = 0x71897568
0x71897568 is an oop
[Lcom.mysql.jdbc.Field;
- klass: 'com/mysql/jdbc/Field'[]
- length: 0
r1 = 0x00000008
0x00000008 is an unknown value
r2 = 0x00000000
0x00000000 is an unknown value
r3 = 0x00000000
0x00000000 is an unknown value
r4 = 0x62922d40
0x62922d40 is an unknown value
r5 = 0x00000368
0x00000368 is an unknown value
r6 = 0x693d65e8
0x693d65e8 is an oop
com.mysql.jdbc.JDBC4Connection
- klass: 'com/mysql/jdbc/JDBC4Connection'
r7 = 0x62922d40
0x62922d40 is an unknown value
r8 = 0x73a51000
0x73a51000 is an unallocated location in the heap
r9 = 0x66c13e30
0x66c13e30 is an unknown value
r10 = 0x63003c00
0x63003c00 is a thread
fp = 0x693d65e8
0x693d65e8 is an oop
com.mysql.jdbc.JDBC4Connection
- klass: 'com/mysql/jdbc/JDBC4Connection'
r12 = 0x718974b8
0x718974b8 is an oop
com.mysql.jdbc.JDBC42ResultSet
- klass: 'com/mysql/jdbc/JDBC42ResultSet'
sp = 0x609adfa0
0x609adfa0 is pointing into the stack for thread: 0x63003c00
lr = 0x73e74bb0
0x73e74bb0 is at code_begin+2176 in an Interpreter codelet
invoke return entry points [0x73e74330, 0x73e74cc0] 2448 bytes
pc = 0x741db028
0x741db028 is at entry_point+520 in (nmethod*)0x741dad08
Stack: [0x60960000,0x609b0000], sp=0x609adfa0, free space=311k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
J 1635 C2 com.mysql.jdbc.ResultSetImpl.<init>(JJLcom/mysql/jdbc/MySQLConnection;Lcom/mysql/jdbc/StatementImpl;)V (314 bytes) @ 0x741db028 [0x741dae20+0x208]
j com.mysql.jdbc.JDBC4ResultSet.<init>(JJLcom/mysql/jdbc/MySQLConnection;Lcom/mysql/jdbc/StatementImpl;)V+7
j com.mysql.jdbc.JDBC42ResultSet.<init>(JJLcom/mysql/jdbc/MySQLConnection;Lcom/mysql/jdbc/StatementImpl;)V+7
j sun.reflect.GeneratedConstructorAccessor17.newInstance([Ljava/lang/Object;)Ljava/lang/Object;+242
J 1634 C2 com.mysql.jdbc.ResultSetImpl.getInstance(JJLcom/mysql/jdbc/MySQLConnection;Lcom/mysql/jdbc/StatementImpl;)Lcom/mysql/jdbc/ResultSetImpl; (65 bytes) @ 0x741e0260 [0x741dff70+0x2f0]
j com.mysql.jdbc.MysqlIO.buildResultSetWithUpdates(Lcom/mysql/jdbc/StatementImpl;Lcom/mysql/jdbc/Buffer;)Lcom/mysql/jdbc/ResultSetImpl;+170
j com.mysql.jdbc.MysqlIO.readResultsForQueryOrUpdate(Lcom/mysql/jdbc/StatementImpl;IIIZLjava/lang/String;Lcom/mysql/jdbc/Buffer;ZJ[Lcom/mysql/jdbc/Field;)Lcom/mysql/jdbc/ResultSetImpl;+18
j com.mysql.jdbc.MysqlIO.readAllResults(Lcom/mysql/jdbc/StatementImpl;IIIZLjava/lang/String;Lcom/mysql/jdbc/Buffer;ZJ[Lcom/mysql/jdbc/Field;)Lcom/mysql/jdbc/ResultSetImpl;+30
j com.mysql.jdbc.MysqlIO.sqlQueryDirect(Lcom/mysql/jdbc/StatementImpl;Ljava/lang/String;Ljava/lang/String;Lcom/mysql/jdbc/Buffer;IIIZLjava/lang/String;[Lcom/mysql/jdbc/Field;)Lcom/mysql/jdbc/ResultSetInternalMethods;+806
J 1596 C2 com.mysql.jdbc.ConnectionImpl.execSQL(Lcom/mysql/jdbc/StatementImpl;Ljava/lang/String;ILcom/mysql/jdbc/Buffer;IIZLjava/lang/String;[Lcom/mysql/jdbc/Field;Z)Lcom/mysql/jdbc/ResultSetInternalMethods; (426 bytes) @ 0x741cb6d8 [0x741cb3f0+0x2e8]
j com.mysql.jdbc.ConnectionImpl.setAutoCommit(Z)V+147
j org.apache.commons.dbcp2.DelegatingConnection.setAutoCommit(Z)V+9
j org.apache.commons.dbcp2.DelegatingConnection.setAutoCommit(Z)V+9
j org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.begin()V+13
j org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.begin()V+12
j org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.begin()V+8
j org.hibernate.engine.transaction.internal.TransactionImpl.begin()V+47
j org.hibernate.internal.SessionImpl.beginTransaction()Lorg/hibernate/Transaction;+41
j org.hibernate.jpa.internal.TransactionImpl.begin()V+42
j org.springframework.orm.jpa.DefaultJpaDialect.beginTransaction(Ljavax/persistence/EntityManager;Lorg/springframework/transaction/TransactionDefinition;)Ljava/lang/Object;+26
j org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(Ljavax/persistence/EntityManager;Lorg/springframework/transaction/TransactionDefinition;)Ljava/lang/Object;+34
j org.springframework.orm.jpa.JpaTransactionManager.doBegin(Ljava/lang/Object;Lorg/springframework/transaction/TransactionDefinition;)V+148
j org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(Lorg/springframework/transaction/TransactionDefinition;)Lorg/springframework/transaction/TransactionStatus;+204
j org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(Lorg/springframework/transaction/PlatformTransactionManager;Lorg/springframework/transaction/interceptor/TransactionAttribute;Ljava/lang/String;)Lorg/springframework/transaction/interceptor/TransactionAspectSupport$TransactionInfo;+37
j org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(Ljava/lang/reflect/Method;Ljava/lang/Class;Lorg/springframework/transaction/interceptor/TransactionAspectSupport$InvocationCallback;)Ljava/lang/Object;+49
j org.springframework.transaction.interceptor.TransactionInterceptor.invoke(Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object;+40
J 1449 C2 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()Ljava/lang/Object; (107 bytes) @ 0x74187c50 [0x74187b90+0xc0]
j org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object;+1
J 1449 C2 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()Ljava/lang/Object; (107 bytes) @ 0x74187c50 [0x74187b90+0xc0]
j org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object;+89
J 1449 C2 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()Ljava/lang/Object; (107 bytes) @ 0x74187c50 [0x74187b90+0xc0]
j org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object;+18
J 1449 C2 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()Ljava/lang/Object; (107 bytes) @ 0x74187c50 [0x74187b90+0xc0]
j org.springframework.aop.framework.JdkDynamicAopProxy.invoke(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;+321
j com.sun.proxy.$Proxy67.save(Ljava/lang/Object;)Ljava/lang/Object;+16
j ro.i2cWebAppController.app.serv.BaseServiceImpl.save(Lro/i2cWebAppController/app/model/BaseModel;)Lro/i2cWebAppController/app/model/BaseModel;+5
j ro.i2cWebAppController.app.schedule.RaspberryPiScheduler.writeRaspberryPiData()V+116
j sun.reflect.GeneratedMethodAccessor64.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+36
J 580 C2 java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (62 bytes) @ 0x73ffafac [0x73ffaf10+0x9c]
j org.springframework.scheduling.support.ScheduledMethodRunnable.run()V+19
j org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run()V+4
j java.util.concurrent.Executors$RunnableAdapter.call()Ljava/lang/Object;+4
j java.util.concurrent.FutureTask.runAndReset()Z+47
j java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Ljava/util/concurrent/ScheduledThreadPoolExecutor$ScheduledFutureTask;)Z+1
j java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run()V+37
j java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V+95
j java.util.concurrent.ThreadPoolExecutor$Worker.run()V+5
j java.lang.Thread.run()V+11
v ~StubRoutines::call_stub
C 0x609aed68
And i found a very strange behaviour. 我发现了一个非常奇怪的行为。 After following the advices from comments, i added the following lines in tomcat starting script :
在遵循注释的建议后,我在tomcat启动脚本中添加了以下几行:
Environment='CATALINA_OPTS=-Xms64M -Xmx192M -server -XX:+UseParallelGC -XX:+UnlockCommercialFeatures -XX:+FlightRecorder'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom -Dcom.sun.management.jmxremote.port=7091 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false'
and i connected Java Mission Control and Flight Recording to raspberry's JVM. 我将Java Mission Control和Flight Recording连接到了树莓派的JVM。 The strange thing is that the JVM didn't crash after 12 hours of monitoring, everything was working ok.
奇怪的是,经过12个小时的监视,JVM并未崩溃,一切正常。 After restarting the server with "XX:+UnlockCommercialFeatures -XX:+FlightRecorder" and "-Dcom.sun.management.jmxremote.port=7091 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" removerd, JVM crashed after 7 hours.
使用“ XX:+ UnlockCommercialFeatures -XX:+ FlightRecorder”和“ -Dcom.sun.management.jmxremote.port = 7091 -Dcom.sun.management.jmxremote.authenticate = false -Dcom.sun.management.jmxremote重新启动服务器后.ssl = false“ removerd,JVM在7小时后崩溃。
And with Mission Control and Flight Recording connected to JVM i also noticed that Committed Heap is allways rising but never dropping. 通过将任务控制和飞行记录连接到JVM,我还注意到Committed Heap一直在增加,但从未下降。
Problem solved after Java update from 1.8.0 to 1.8.0_65. Java从1.8.0更新到1.8.0_65后解决的问题。
Thank you for tips. 感谢您的提示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.