基本原则
每写一个模块就测试一下,写出其对应得Test方法进行测试,及时发现问题。
如果出现错误,可以采取以下几种方式进行排错:
- 可以插入System.out.println()函数在不同的地方输出相关信息(这种仅仅是针对已知道问题大概在哪,一般是项目不大的时候可以采用)。
- 可以自定义异常类,在适当的位置进行抛出,然后进行捕获。
- 采用代码编辑器的Debug工具,我用过的很多编辑器都是有Debug功能的,Java方面Idea 和Eclipse都有,Python的Pycharm编辑器,C++的Visual studio,甚至我曾经做控制算法的Uvision编辑器都有。像在出现404请求错误或者500程序错误的话,用debug就能很方便的去调试出代码的问题。
- 但是如果项目过大,根本不知道错误在哪的话,尤其是一些运行时异常,这样也不好打断点,总不可能到处都去打断点,可以借助一些第三方工具,例如MAT,Jprofiler。
- 查看日志信息和堆栈信息。在mysql数据库读写的时候,查看日志信息经常使用。
常见错误及排错方法:(持续更新)
1. 出现OOM(out of memory Error)、heapOverflow 等类似的运行时错误。
解决办法:
采用Jprofiler软件,MAT,Jprofiler作用:
分析Dump内存文件,快速定位内存泄漏
获得堆中的数据
获得大的对象
…
将Jprofiler在编辑器中配置好,然后设置VM options -Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError后,再次运行,控制台输出:
然后找到HPROF快照
双击打开,可以通过多种方式定位错误,通过实时内存查看
通过线程查看
这里说一下上述提及到的VM options参数:
-Xms 设置初始化内存分配大小,默认1/64
-Xmx 设置最大分配内存,默认1/4
-XX:+PrintGCDetails 打印GC垃圾回收信息
-XX:+HeapDumpOnOutOfMemoryError 生成oomDump文件
-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
-Xms1024m -Xmx1024m -XX:+PrintGCDetails
对于不同的错误,只需要针对下面的命令修改错误类型就行,
VM options -Xms1m -Xmx8m -XX:+HeapDumpOnXXX
VM options -Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
2. bean不存在,报空指针异常(SpringMVC时的错误)
解决办法:
- 查看bean是否注入成功 ,发现ok
- Junit单元测试,看下代码是否能够查询出结果出来, 发现ok,因此将问题定位到Spring部分
- SpringMVC整合的时候没有调用service层的bean
- applicationContext.xml没有注入bean
- web.xml中,没有绑定配置文件!发现问题,配置的Spring-mvc.xml这里面确实没有service bean,所以报空指针异常。
3. 对于404请求错误等
一般就是在@controller注入处、servlet程序处理的地方打上断点,debug调试,看看请求到底过去没有。
4. 并发修改异常(java.util.ConcurrentModificationException.)
在并发下的集合都是不安全的(除了Vector,因为Vector默认是线程安全的)。
解决方法:
- 采用Vector来替换,但是这也是最笨的解决方案。
- 采用Collections.synchronizedXXX就可以解决。
- 对于List的话,还可以采用JUC里面的CopyOnWriteArrayList<>()来解决;对于Set可以采用CopyOnWriteArraySet<>()来解决;对于Map可以用ConcurrentHashMap<>()来解决。这是采用写入时复制的思想,先把原来的东西复制一份,然后再写入,最后把复制的东西插入回去。这样就避免了写入覆盖的问题,而且这种方法比Vector高效。
4. 进程卡住
解决办法
-
在Linux下可以采用top查看进程信息,也可以在Idea工具的terminal终端中输入 jps -l 定位进程号
-
定位到进程号后,采用 jstack 进程号 查看堆栈信息,一般来说如果是进程卡住的话,往往都是死锁造成的,此时用 jstack xxx 命令就可以查看到相关信息。
5. 数据库内容正确修改,但是页面出现错误
这是我在用springboot整合Mybatis时出现的错误,界面出现错误,但是数据库成功操作了,界面错误如下:
控制台输出错误如下:
2021-03-23 20:03:56.654 ERROR 15492 — [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.ibatis.binding.BindingException: Mapper method 'com.example.springbootmybatis.mapper.UserMapper.addUser attempted to return null from a method with a primitive return type (int).] with root cause
org.apache.ibatis.binding.BindingException: Mapper method 'com.example.springbootmybatis.mapper.UserMapper.addUser attempted to return null from a method with a primitive return type (int).
解决办法:
- 检查配置问题,确认配置没有问题后
- 采用debug调试,缩小问题所在
- 观察控制台错误信息,由于错误提示在Mapper method ,所以去仔细查看UserMapper.xml文件,最终发现问题在于sql语句写错了,