Hotspot源码解析-第十一章

第十一章

11.1 线程

11.1.1 线程的概念

说起线程,首先得提起进程,相信很面试者在回答进程与线程的区别时都会用一句话:“进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位”,只能说这句话部分正确,就目前来讲,一般操作系统(这里指Linux)的任务调度执行单位确实是线程,但是未来可能会支持以协程为单位的任务调度。再说进程是操作系统资源分配的基本单位这句话,在linux操作系统中,当需要创建一个进程时,通过系统调用fork()然后再调用copy_process来完成,创建进程时,会创建并分配该进程所需要的任务资源和内存,最终形成图11-1的内存模型,粗略分为代码块(存放代码数据)、数据块(涉及数据的存放)、堆(进程malloc动态分配内存区)、用户栈(进程执行时动态存储区)、共享库存储映射区(主要是映射动态库或其他依赖库)等,这些区域在进程创建时都是要先创建的(虚拟空间),这些虚拟空间都是要占用一定内存的,也就是所谓的进程的资源分配的一部分,当然还有其他资源的分配,比如页目录、页表等。然而,这个时候线程去哪里了呢,其实,这个时候同时创建出了一个线程(概念上的),最终形成一进程一线程模型。如果该进程在执行的过程中再通过pthread_create()函数创建另外一些线程,那就形成了一进程多线程模型。由于linux底层线程的创建函数,底层也是copy_process()函数来完成的,实现上创建过程跟fork()创建进程是一样的,只是创建线程时,不会再创建图11-1描述的空间,而是继承发起线程创建者的这块空间。最终总结线程和进程的区别:

1、进程和线程创建过程本质上是没有区别的,最终都是通过copy_process()函数调用

2、进程只是在概念上包含了线程,以进程为调度单位时,本质上就是一进程一线程的模型在运行,早期的linux调度模型就是这样的

3、进程的概念实际上就是早期以进程为调度单位提出的,所以从技术上讲,没什么区别,只是人为制定的概念加以区分

图11-1

Hotspot源码解析-第十一章_第1张图片

11.1.2 Hotspot线程

在执行命令 java [options] xxx.class param1 param2 ... paramn 时,实际上Linux是fork()出了一个新的Java进程来执行后续操作,并且在执行的过程中又会创建其他的线程(Java线程、VM线程、GC线程等)。然而在Java执行的过程中,是需要Java线程与VM双向交互的,例如:在线程的启停时需要执行一些必要的任务(比如保存安全点),以及垃圾收集期间线程的协调和同步,所以Hotspot JVM需要管理这些线程,但是线程又是有操作系统创建的,不是JVM创建的,因此在Hotspot中,每个Java线程都会映射到一个操作系统线程,同时需要跟踪和管理这些线程,确保Hotspot内部的状态与线程本身状态同步。

11.1.3 线程关系

Hotspot中,各线程类的关系图,如图11-2
图11-2
Hotspot源码解析-第十一章_第2张图片

11.1.4 线程的属性

属性名 功能描述 归属类
_pending_exception 指向当前线程等待处理的异常对象的引用 ThreadShadow
_exception_file 指向异常发生时的文件信息 ThreadShadow
_exception_line 指向异常发生时的代码行信息 ThreadShadow
_real_malloc_address 指向线程创建时分配的实际地址的首地址 Thread
_SR_lock 线程状态更改的监视器 Thread
_suspend_flags 线程挂起标志 Thread
_num_nested_signal 进入线程内部处理linux系统信号的个数,处理完成后会-1 Thread
_active_handles 指向当前线程持有的JNI句柄链表头指针 Thread
_free_handle_block 空闲JNI句柄块的链表头指针 Thread
_last_handle_mark HandleMark的指针,该Mark会记录指向线程本身、存储区域、存储chunk等信息 Thread
_tlab 线程本地分配缓存 Thread
_allocated_bytes 当前线程在Java堆中已分配的字节数 Thread
_vm_operation_started_count 记录已开始的VM操作数量 Thread
_vm_operation_completed_count 记录已完成的VM操作数量 Thread
_osthread 指向基于平台的线程实现 Thread
_resource_area 线程本地的用于临时分配的资源区域 Thread
_handle_area 线程本地的用于分配JNI句柄的资源区域 Thread
_stack_base 线程栈基址 Thread
_stack_size 线程栈大小 Thread
_ParkEvent 线程阻塞时的事件对象 Thread
_SleepEvent 线程睡眠时的事件对象 Thread

你可能感兴趣的:(Java虚拟机,java)