深入浅出教你理解jvm虚拟机结构篇

前言

  • JVM详细文章,看过本篇之后有选择的继续看
  • 结构图
  • 怎么去理解?

大部分技术文章感觉过于晦涩难懂,我写文章的目的和初衷是教大家如何去理解和运用这些基础知识,只有理解了才记得住,只有理解了才会运用。

JVM详细文章,看过本篇之后有选择的继续看

JVM堆内存详解

结构图

首先是jvm结构图,这个老生常谈,不需要多做解释。上图深入浅出教你理解jvm虚拟机结构篇_第1张图片

怎么去理解?

首先我们想象一个这样的场景,有一块刚从政府手里买的空地,可以在空地上建房子,但是房子比较特殊,要建的房子结构都是一样的;这个结构都一样的房子内部又可以划分成5个房间,然后里面有个人**(此人就是线程)开始干活,重点在于这个人如何装修这个房子,这个人还分灵魂和肉体**。
第一个房间(方法区):装载**模具(class对象)和成熟工具(成熟工具就是静态的对象或者常量)**的,这个模型可以有床的模具,碗的模具,总之啥模具都有,想要啥模型,你自己就写个java类就可以了;除了模具还有些现成的工具,比如电锯,当然这里面电锯的模具也有,但是电锯可能是经常用到的东西,所以提前做好准备着随时用到;
第二个房间(堆区):存储实物的,实物都是人用模具造出来的;
第三个房间(虚拟机栈):工作区,房间里的这个人干活的地方;
第四个房间(程序计数器):记录区,记录这个人干活的进度,有可能休息,然后继续做
第五个房间(本地方法去):高级工作区,做一些人力达不到工作或者效率比人高的工作;
干活的人(线程):具体干活的

方法区会加载各种类,把class、常量加载到方法区中,每个类只加载一次(保证类只加载一次的机制叫双亲委派机制);因为模子只需要一个就可以了;
虚拟机栈开启一个任务栈,就是一个线程开始工作,第一个main线程会从main方法开始执行;当线程执行到new一个对象的时候,就从方法区中找到这个类的class对象,然后创建一个具体对象存在堆中;执行的过程中会有程序计数器记录该线程的执行位置;每个线程都会开启一个任务栈;方法会封成栈帧,存在自己的任务栈中,所以方法中的变量不能共享;全局变量是存储在堆中,所以全局变量可以线程共享;虚拟机栈中为线程开启的任务栈,就像我们工作中自己的每个工位一样,肯定不能两个人在一个工位上干活,那样肯定全乱套了,下图大概栈的执行过程,和源代码

public class Test {
     

    private Object object;

    public static void main(String[] args) {
     
        Test test = new Test();
        test.object = new Object();
        test.doSomething(test.object);
    }

    public void doSomething(Object object) {
     
        System.out.println(object.hashCode());
    }
}

深入浅出教你理解jvm虚拟机结构篇_第2张图片
上图右边描述文字漏了一些内容,继续补充:hashcode执行完,有个int结果,执行完该栈帧进行释放内存,然后就不存在了,然后继续执行中间的doSomething()方法,把System.out.println(object.hashCode());里的object.hashCode()替换成返回来的int,然后就继续执行打印方法了

下面是对象的创建过程,本来想画一个整个虚拟机的执行过程图,但是心灵手不巧,不知道该用什么工具画类似的图
深入浅出教你理解jvm虚拟机结构篇_第3张图片

话说回来,这个人干活的过程就是就是虚拟机的执行过程,这个线程想通过模具制造一个柜子,就找到柜子的模具,然后就可以打造出来了;下面我们来利用这个场景来回答一些常见问题:
1、线程和进程的区别
官话:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位;
个人理解:进程就是一个程序,就是建造一个房子,然后让房子里面的人开始干活,什么是资源分配?就是建造房子需要一块地,在这片地上给你个位置,让你建造这栋房子;分配这块地给你就是分配给你的基本单位;而线程是什么?线程是房子里具体干活的人,而这个人有肉体和灵魂;为什么分肉体和灵魂呢,比如一个四核心8线程的cpu,实际整个电脑的线程就8个;而我们java创建的线程分如下生命周期深入浅出教你理解jvm虚拟机结构篇_第4张图片
创建一个线程就算你执行了start()方法,也不是立马执行的,要等到cpu的调度;这就是为什么人要分灵魂和肉体,肉体是我们自己new Thread();只有等cpu的8个线程,每个线程都是一个灵魂附体的时候,我们房子里的人才开始干活;才能动;
我们知道第四个房间程序计数器,其实意思就是这个灵魂日理万机,他的时间是分段的,每段可能就几毫秒(CPU时间片是直接分配给线程的,线程拿到CPU时间片就能执行了),同时有好多房子(虚拟机)在搞装修,每个房子里面至少有一个人在干活,房子的数量肯定是超过cpu总线程8个的,所以灵魂不够用怎么办?就是把灵魂的时间分段,给段分配给一个人;这样就可以很多人同时干活了;更重要的是灵魂从其他地方回来的时候,不知道当前的活干到哪了,所以需要第四个房间程序计数器,记录执行过程;

两个人干活的时候,肯定要独立进行,不能进行互相打扰,所以虚拟机栈在干活的时候会给每个线程分配独立的任务栈,所以栈不是线程共享的,如果两个人共享那么干活就乱套了

以此为基础、后面的快进程通信、内存映射、handler都可以通过我当前讲述的现实场景进行解释!今天先写到这里,欢迎关注,后面会出具体的堆区、方法区、栈区的技术文章。有哪里不明白的欢迎留言,我会继续更新

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