用户态与内核态之间的区别

215 阅读2分钟

概括

内核线程(KLT):是操作系统的线程(操作系统的内存也就是内核态内存)

用户线程(ULT):用户线程则是跑在操作系统上的线程(操作的内存用户态内存),不由计算机来管理,直接由程序来管理,对操作系统只暴露进程的概念

用户内存:JVM的内存

内核内存:操作系统使用的内存

直接内存:非上面两种,单纯存放于内存中

(一般程序操作一块内存是需要将直接内存引入到用户内存中操作,但是可以通过一定手段来操作直接内存被称为零拷贝,当然零拷贝不单单指着一种)

程序接收网络请求

首先需要网卡收到数据后需要由内核线程读取到内核内存中,再将内核内存拷贝到直接内存中,再由用户线程加载到自己的用户内存中(这样以来就经历了两次拷贝,一个来回就是4次拷贝。当然可以对这做出优化Netty就做了优化,不再将直接内存中的数据拷贝的用户内存中来,直接操作直接内存。这个东西在Java里面也有实现:DirectByteBuffer,相反的就是HeapByteBuffer)

JDK为何使用内核线程

用户线程的优点

  • 创建的成本低:直接在程序中就可以创建无需调用内核方法
  • 系统的开销小:线程由程序来管理,就省去可操作系统的操作

用户线程的缺点

  • 如果是需要对系统核心的功能进行访问的情况需要从用户态转换为内核态的形式,在操作完成后还需要将其更改回来,这样的开销是非常大的
  • 当一个用户线程发生了阻塞状态,操作系统是没法及时发现处理来切换其他的应用线程来跑,这样还会造成资源的浪费

内核态线程的优点

  • 可以利用到内核的高权限如:IO磁盘等操作
  • 可以吃到操作系统的优化如:在一个线程发生阻塞的时候由于优化算法的存在会让CPU更快的发现阻塞线程来处理或者是切换

内核态线程的缺点

  • 切换的成本高:需要CPU发生上下文的切换
  • 创建的成本高:在创建时需要直接调用内核方法来创建线程

这样一看,JDK当然是选择性能更高的内核态线程,因为考虑到JVM自带线程会频繁与磁盘IO(加载类)这样可以省去从用户态到内核态频繁的切换。以及可以将线程管理交给CPU来管理减少压力。