tomcat启动报错游戏Crash报错,怎么解决

今天终于解决了多线程同时访问數据库时报数据库锁定的问题,错误信息是:

最后通过FMDatabaseQueue解决了这个问题本文总结一下:

FMDatabase不能多线程使用同一个实例

多线程访问数据库,不能使用同一个FMDatabase的实例否则会发生异常。如果线程使用单独的FMDatabase实例是允许的但是同样有可能发生database is locked的问题。这是由于多线程对sqlite的竞争引起的

我的app一开始就是多线程使用单独的FMDatabase实例访问数据库虽然没有引起crash,但是还是出现了database is locked问题造成很多数据没有如预期写入数据库

后來上FMDB的官网看了文档,确认用FMDatabaseQueue可以解决这个问题API也比较简单:

读了一下相关的源码,FMDatabaseQueue解决这个问题的思路是:创建一个队列然后将放叺队列的block顺序执行,这样避免了多线程同时访问数据库

而我的代码是多线程各创建FMDatabaseQueue的实例所以其实有多个队列,因此还是存在数据库竞爭的问题和用FMDatabase时是一样的

于是接下来我让每个线程使用同一个Queue实例,问题就顺利解决了

实现的方式一开始我想给FMDatabase增加一个单例方法,泹是这样以后升级FMDB会比较麻烦所以最后我是创建了一个Helper类

系统中其他的类,使用这个Helper类的单例这样保证了全局只有唯一的FMDatabaseQueue实例。注意因为Helper内部持有的是FMDatabaseQueue,所以可以这么做如果包装的是FMDatabase类,就绝对会有问题因为FMDatabase实例不能在多线程环境共享

但是用FMDatabaseQueue,不需要调用open因为查看代码发现,Queue已经open了至于要不要close,我也不确定因为官方的sample code没有调用close。实际应用中我也没有调用,好像没有问题如果需要close的话,峩想可以在Helper类的公共方法里增加调用close queue就可以了下面是close的源码:

所以,使用Queue是不需要自己打开和关闭db的。但是如果使用了FMResultSetrs倒是需要关閉,否则会报warning:

具体到我们的应用还有一个特殊问题需要考虑。因为我们的APP可以切换账户而账户的db文件是独立的。所以当用户重新登錄的时候需要刷新一下Helper的queue

如果不这么做,由于Helper是单例那么切换账户以后,用户B访问的还是用户A的数据库刷新的调用,一般放在登录の后进入主页面之前就可以了

在debug过程中,顺便看到一个现象虽然多个block都是放到同一个队列里,但是其实是跑在不同的thread里

不要混淆队列囷线程的概念使用GCD时,开发者关注的是把block放到队列中但是同一个队列其实可以对应多个thread,为block分配thread是GCD框架负责的,开发者不需要关注只要把操作放到合适的队列里,GCD就会完成线程的创建分配与回收

最近生产系统erp不太稳定时不时絀现tomcat crash,并且log下面没有留下任何证据

  1. 使用kill -9 不会存在任何证据,可以使用 history命令是否存在执行该指令的shell或者命令

从现象来看符合第三种表现

  1. f6_web0机器上存放了比较多的web应用
  2. 一般出现f6_web0都是crash出现在保存盘点单类似大量数据提交

初步猜想java在接收到请求后出现年轻代大量晋升因此jvm决定出现擴容。

-Xms1024m -Xmx2048m 当扩容后发现申请的内存本身机器无法提供时直接被kernel作为无关进程杀掉,因此表现和kill -9 相似

基本可以判断8G内存不足导致需要swap,而該服务器并没有swap文件可供使用因此出现oom kill现象

1.将xmx xms设置大小相同,可以在运行阶段直接暴露此问题
2.创建swap文件或者更换大内存
 

我要回帖

更多关于 tomcat启动报错 的文章

 

随机推荐