繁体   English   中英

Raspberry PI 2 Java 8 JVM错误

[英]Raspberry PI 2 Java 8 JVM error

我正在构建基于Java 1.8,spring,hibernate,mysql的Web应用程序,并使用tomcat作为Web服务器。 现在我的应用正在记录(每隔5秒)树莓的系统数据,例如: cpu温度,cpu核心电压,已用内存,可用内存,内存缓冲区等。问题是应用程序不时崩溃是因为它的内存不足,我无法确定原因。

首先,在tomcat上,tomcat的启动服务中包含以下几行:

Environment='CATALINA_OPTS=-Xms256M -Xmx512M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'

并且在启动tomcat之后约8小时内崩溃了。 我删除了这些行,现在由于内存不足,它在大约2天后崩溃了。 今天,这是它第一次崩溃,但启动脚本中没有这些行,而我在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

对于此信息,我正在使用pi4j库中的SystemInfo类。 getMemoryUsed()返回以位为单位的已用内存,因此在简单的数学运算之后,我们得到的已用内存为913.92 Mb。

启动应用程序时,它仅消耗250 Mb的内存,而3天后崩溃的原因是应用程序达到了树莓派的最大内存。

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;
    }
}

调度程序类:

@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);
            }
        }

    }

}

基本回购:

@NoRepositoryBean
public interface BaseRepo<T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {
}

现在我在日志中找不到错误,但是在过去,它因SIGILL错误而崩溃。 找到日志后,我将编辑此帖子。

我发现了来自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

我发现了一个非常奇怪的行为。 在遵循注释的建议后,我在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'

我将Java Mission Control和Flight Recording连接到了树莓派的JVM。 奇怪的是,经过12个小时的监视,JVM并未崩溃,一切正常。 使用“ 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小时后崩溃。

通过将任务控制和飞行记录连接到JVM,我还注意到Committed Heap一直在增加,但从未下降。

Java内存堆图

Java从1.8.0更新到1.8.0_65后解决的问题。

感谢您的提示。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM