标签归档:Java

对NIO的几点理解

一、基本概念
Blocking IO VS NonBlocking IO
阻塞IO:线程会一直等待/阻塞直到IO操作完成,比如准备读取10个字节的数据,但是现在只读了8个,那么当前线程会一直等下去,直到读取到剩下的2个字节的数据。这是普通IO的线程模型:
bio-png
非阻塞IO:在进行IO操作时线程并不会阻塞(等待),一次只读取能读取的数据,读完立刻返回,然后线程会去继续处理其他事情。等下次可读的时候被唤醒,再来读取数据。这是NIO的线程模型:
nio-png
因此在阻塞IO模式下,如果你要处理N个请求的话,就需要开启N个线程分别处理这些请求。因此最大的连接数取决于服务器能开出的最大线程数,虽然后期采用线程池的方式做了些优化,但总体而言性能并没有很大提升。而在非阻塞IO下只要一个线程就够了,不断的在各个连接之间切换,在某个连接有可用事件的时候通知主线程。
咋一看是不是很容易理解?但是对于NIO的工作模式我一直有个疑问:

主线程立即返回了,那读写数据的时候总得消耗线程吧?

其实真正的IO操作是内核线程,但上层也需要用户线程去调用。而且NIO所说的用户线程立刻返回并不是说不消耗线程,而[……]

继续阅读

java进程coredump(二)

上篇介绍了如何生成一个Java进程的coredump,今天则来总结下当Java进程挂掉之后应该怎么样一步一步来分析。

一、Fatal Error Log
接着昨天的例子继续看,在coredump之后目录里面的文件是这样的:

一般情况下当Java进程挂掉之后,在程序目录下面会生成一个错误日志:hs_err_pidxxxx.log。这个文件是你排查问题的过程中第一个应该阅读的日志,因为这个文件里面会记录很多有用的信息,比如:线程堆栈,堆的使用情况,JVM参数和环境变量,虚拟机状态,操作系统信息等。这里提供的信息非常多,也非常全面,为我们大致定位问题提供了很大的帮助。
先来看下文件开头的注释信息,这里的信息很粗略地指出了崩溃的原因:

第8,9行指出了出现问题的栈是在动态库crash.so的Java_CoreDumpTest_crash方法。接下来看下具体的堆栈信息:

继续阅读

java进程coredump(一)

上篇文章介绍了coredump的基本知识以及gdb调试core文件的相关操作,这篇文章主要介绍如何生成Java进程的coredump,也就是说如何写一段java代码使它被操作系统kill掉。我们都知道因为jvm的存在,java层面的代码无论你怎么写都是不太可能crash的,顶多是OOM或者stackoverflow,然而这些都会被jvm捕捉并抛出异常,而不是被操作系统直接kill掉。所以如果一个java进程crash掉,那肯定是挂在native code上了(当然JVM本身的bug就另说了),因此思路就是通过java的JNI(java native interface)调用本地方法,使进程挂掉。具体步骤如下:

1.编写java代码,调用本地方法

2.编译,生成.class文件

3.生成头文件:CoreDumpTest.h

该文件的内容如下:
[cr[……]

继续阅读

core文件的生成和调试

上一篇文章匆忙地记录了一次分析core文件报错的过程,今天则花点时间来认真总结下Linux下core文件的开启,生成,调试,以及堆栈定位。

一、什么是core文件?
进程在运行时可能会因为各种各样的原因(后面会细说)崩溃,而在崩溃前的一瞬间操作系统会像拍照片一样生成一个core文件,这个文件记录了程序运行时的状态,主要包括内存信息,堆栈指针,寄存器状态等,生成core文件的这一过程俗称为coredump。开发人员可以通过对core文件的分析来排查,定位问题,找到程序崩溃的原因。

二、core文件设置

a).如何开启

这条命令输出的是允许生产core文件的最大size,如果是0则表示你没有开启coredump,如果是unlimited则表示不限制大小。所以如果要开启coredump,只需要输入:

其中,unlimited可以换成具体的数字,比如1024(单位是KB)。

b).文件名及目录
默认设置下,
1.core文件是[……]

继续阅读

Can’t attach to the core file

今天在使用jsadebugd调试core文件的时候又报错了:
Error attaching to core file or starting server: sun.jvm.hotspot.debugger.DebuggerException: Can’t attach to the core file
堆栈如下:

之前碰到这个报错的时候甚至去看了jdk的源码,但还是一无所获。今天灵光一现,通过分析和不断尝试,大致可以总结出有以下几个原因:
1.core文件损坏

2.调试的command不正确,这个工具的使用格式是这样的:

executable必须是java的全路径,而不能是java
所以这样使用是会报错的:

正确的使用方式是:

3.调试用的jdk版本和当时出core的jdk版本[……]

继续阅读