java程序运行时发生的系统调用

程序没法直接访问数据(硬件:磁盘、网卡),程序须要经过内核访问,内核提供syscall,syscall的方法不能直接调用(保护模式),因此就有了软中断,中断做用在cpu中,cpu收到中断后,cpu会根据中断号去内核中找对应的callback...java

程序测试

下面经过一个简单的例子进行说明,下面这段代码是测试socket简单的一个方法,应该比较好理解(其实就是经过多线程解决多链接的问题),将下面这个java文件放在linux执行看下linux

public class TestSocket {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8090);
        System.out.println("step1:new ServerSocket(80)");
        while (true){
            Socket client = server.accept();
            System.out.println("step2:client\t"+client.getPort());
            new Thread(() ->{
                try {
                    InputStream in = client.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                    while (true){
                        System.out.println(reader.readLine());
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }).start();
        }
    }
}
复制代码

程序抓取

经过下面这个命令抓取上面程序执行时对于内核有没有发生系统调用shell

strace -ff -o ./ooxx java TestSocket
复制代码

执行后能够看到打印了第一句话,说明程序已经执行,发生了阻塞 markdown

经过其余窗口进入这个文件夹发现产生了一堆文件网络

其实这些文件都是线程,那么哪一个文件是主线程呢?能够经过代码中的关键字查找下多线程

-- 查找包含step1 的文件
grep 'step1' ./*
复制代码

果真其中最大的这个163文件有个"write(1, "step1:new ServerSocket(80)", 26) = 26"socket

能够打开这个文件看下,能够找到这个操做在文件中的位置(具体的含义咱们后面再分析)测试

进程线程分析

另外能够经过jps查看线程spa

在linux中一切皆文件,能够看看162这个进程中有哪些东西,能够进入linux根目录下的/proc/进程id 目录中查看,有看到一堆东西 操作系统

先看下task文件,打开这个会发现这些数字是否是和上面ooxx.*是同样的呢,没错其实这个jdk进程中的线程,知道这个以后你就能够查看本身应用下的线程数量

还有一个目录fd,能够看到一些数据这里面的东西叫文件描述符,任何一个程序都有io,0、一、2是三个基本的io

  • 0 标准输入
  • 1 标准输出
  • 2 错误输出

这些流在java中是对象,在操做系统中都是文件,经过数字的方式表明,相似于java中的变量

  • 三、4 是java程序特有的库
  • 五、6 实际上是咱们的程序启动后的server会监听8090,两个分部是ipv四、ipv6

经过网络状态这个命令 netstat -natp;能够看到state是LISTEN状态,只有服务端有监听状态,客户端能够经过这个端口号链接

系统调用分析

那么咱们用nc命令链接看看,能够看到一个链接进来java程序中多一个记录,而且文件描述符相比以前也多了一个socket

nc localhost 8090
复制代码

网络链接

文件描述符

而后一开始程序所在的文件夹,找到主线程,打开后查找先链接的端口号49482;能够看到

accept(6, {sa_family=AF_INET, sin_port=htons(49482), sin_addr=inet_addr("127.0.0.1")}, [16]) = 7

回顾下以前的方法有个server.accept(),内核中也有accept,能够理解java中的一些方法是对内核的包装;在主线程的文件中能够看到生成的文件描述符以及程序执行发生具体的系统调用

你也可使用man命令查看各类指令的做用; 先介绍到这里吧,后面会继续介绍下nio的一些内容

相关文章
相关标签/搜索