JVM启动流程

1.java虚拟机启动的命令是通过java +xxx(类名,这个类中要有main方法)或者javaw启动的。

2.执行命令后,系统第一步做的就是装载配置,会在当前路径中寻找jvm的config配置文件。

3.找到jvm的config配置文件之后会去定位jvm.dll这个文件。这个文件就是java虚拟机的主要实现。

4.当找到匹配当前版本的jvm.dll文件后,就会使用这个dll去初始化jvm虚拟机。获得相关的接口。之后找到main方法开始运行。

上面这个过程的描述虽然比较简单,但是jvm的启动流程基本都已经涵盖在里面了。

jvm的基本结构

类加载器子系统就是通常我们所说的ClassLoader类加载器,首先我们会通过ClassLoader加载到jvm的内存中去,本地方法区主要就是native的方法调用,这个我们不前不做关心,

pc寄存器

1.每个线程拥有一个pc寄存器。
jvm会为每一个线程分配一个pc寄存器,这个pc寄存器总是会指向下一个指令的地址。这样程序在执行过程中pc寄存器总是会知道下一步会做什么。在执行本地方法的时候,pc寄存器的值总是未定义的。

方法区

方法区是用来保存类的原信息。用来描述类的信息,包括类型常量池,字段方法信息,方法字节码。在JDK6的时候字符串常量是放在方法区中,但是JDK7的时候就已经移到了堆中。所以从这方面来说方法区,堆中到底保存的是什么信息和jdk的版本有很大的关系。从一般意义上来说我们的方法区就是保存一些类的原信息。方法区通常和永久区(perm)关联在一起,保存一些相对稳定的数据,

java堆

1.java堆应该是和程序开发中最为密切的一个内存区间,我们在程序开发中通过new出来的对象基本上都是保存在java堆中。
2.堆是全局共享的,所有线程都共享java堆,也就是你创建了一个对象之后,所有的线程都是能够访问的。
3.从GC的角度看,java堆的结构和GC的算法是有关系的。

java栈

1.java栈和堆相比是线程私有的,栈是由一系列帧组成的,所以java栈也叫作帧栈。帧中保存的内容是一个方法的局部变量,操作数栈,常量池指针。每一次方法调用都会创建一个新的帧,并压栈。
我们来看一段C++代码
在上面代码中method()这个方法中,我们new了一个对象,那这个new的对象就是在堆上分配的,但是在堆上分配有一个问题就是每次我们new一个对象之后都要手动把这个对象去删除,释放内存。如果我们多次在堆上分配了对象空间,但是却忘记了删除对象,就会出现内存泄露,就是我们分配空间却没有删除。内存泄露在实际开发中是非常难以解决的问题,因为内存泄露有可能发生在任何地方。 
我们可以采用右面的方法,声明一个对象,我们像上面右面的方法中声明一个对象,那么他并没有实际的划分内存空间,而只是在java栈上产生了一个引用。而这个引用在我们使用后会自动释放,不会产生内存泄露的问题。

java栈上分配好处

栈上分配的一般都是比较小的对象,在没有逃逸(逃逸是指这个对象创建出来之后不仅仅只在当前线程中要使用,其他的线程也要调用的情况)的情况下,直接分配到栈上。GC可以自动回收,减轻GC的压力。大对象或者逃逸对象无法分配到栈上。
我们从上面的代码和主时中可以交互,一个程序要想执行是需要几个内存区域交互配合执行的。
从上面这个图中我们可以发现,每个线程读取和存储的都是线程的工作内存。而线程的工作内存再到主存中的存储是肯定会有一些时差的。也就是改变了一个变量的值之后,另一个调用这个变量的对象是不能马上知道的。如果说要让其他线程立即可见这个改动,就要使用volatile关键字修饰。一旦使用这个关键字之后,所有调用这个变量的线程就直接去主存当中拿取数据。
下面这个图就是线程和本地内存和主存之间的关系。
 
线程总是在自己的本地内存中拿取变量,而本地内存中存储的只是共享变量的一个副本,真正的共享变量是存储在主存中的。所以这个之间存在了一定的时延和误差。

可见性

可见性是指一个线程修改了变量之后,其他线程能够立即知道。
保证可见性的方法就是上图提到的三种方法。
 

有序性和指令重排

有序性:在一个线程当中,所有的指令,所有的操作都是有序的。但是在线程外观察,在多线程的情况下去观察前面一个线程的行为,我们会发现这个行为有可能就是无序的(这种无序有两种原因,一种就是指令重排,另一种就是主存同步的延时,也就是说在线程A中更改了一个变量的值,同步主存也成功了,但是在线程B中我们可能还没来得及去同步主存中的值,这个时候对于线程B来说线程A的操作可能就是无序的)。
指令重排的基本原则:
1.程序顺序原则,一个线程内保证语义的串行性。
2.volatile规则:volatile关键字变量的写是先发生于读的。
3.锁规则:解锁必然发生于随后的一个加锁之前。
4.传递性:A先于B,B先于C,那么A必然先于C。
5.线程的start方法先于它的每一个动作。
6.线程的所有操作先于线程的终结(Thread.join())。
7.线程的中断(interrupt())先于线程被中断的代码。
8.对象的构造函数执行结束于funlize()方法。

java之Jvm学习--JVM运行机制的更多相关文章

  1. JVM学习笔记-运行时数据区

    不同于C,C++程序,Java程序的内存管理工作由Java虚拟机(JVM)接管,这减低了java程序员的负担,但如果出现内存泄露与溢出问题如报OutOfMemory,StackOverFlow异常错误 ...

  2. java 基础知识学习 JVM虚拟机参数配置

    1) 设置-Xms.-Xmx相等: 2) 设置NewSize.MaxNewSize相等: 3) 设置Heap size, PermGen space: Tomcat 的配置示例:修改%TOMCAT_H ...

  3. java入门(1) 程序运行机制及运行过程

    首先我们来看一下java程序在底层是怎么工作的: JAVA有两种核心机制: Java虚拟机(Java Virtual Machine): 1.java虚拟机可以理解成一个以字节码为机器指令的CPU. ...

  4. JVM学习--jvm监控和故障处理工具

    java虚拟机性能监控常用命令 Sun JDK监控和故障处理命令有jps.jstat.jinfo.jmap.jhat.jstack . 1.jps jps:JVM Process Status Too ...

  5. JVM学习-jvm结构(一)

    java是跨平台的语言.一次编译多端使用.究竟是如何实现的呢 1.首先编译器会将java 文件编译成class文件.然后在不同的平台使用对应的虚拟机.不同虚拟机的内装载系统将class文件转换平台能执 ...

  6. 探讨JVM运行机制和执行流程

    JVM是什么 概述 JVM是Java Virtual Machine的缩写.它是一种基于计算设备的规范,是一台虚拟机,即虚构的计算机. JVM屏蔽了具体操作系统平台的信息(显然,就像是我们在电脑上开了 ...

  7. JVM学习(1)——通过实例总结Java虚拟机的运行机制

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: JVM的历史 JVM的运行流程简介 JVM的组成(基于 Java 7) JVM调优参数:-Xmx和-Xms ...

  8. JVM学习001通过实例总结Java虚拟机的运行机制

    JVM学习(1)——通过实例总结Java虚拟机的运行机制-转载http://www.cnblogs.com/kubixuesheng/p/5199200.html 文章转载自:http://www.c ...

  9. JVM学习(1)——通过实例总结Java虚拟机的运行机制(转)

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: JVM的历史 JVM的运行流程简介 JVM的组成(基于 Java 7) JVM调优参数:-Xmx和-Xms ...

随机推荐

  1. CentOS6.x 下 /etc/security/limits.conf 被改错的故障经历

    Intro 我司本小厂,每个员工都是身兼数职,所以开发人员直接登录线上服务器改东西是常态.有些开发人员,自持水平较高(的确水平也是较高,但缺乏对系统的敬畏),所以总是越俎代庖,改一些本身应该是线上运维 ...

  2. 我的Python笔记04

    摘要: 声明:本文整理借鉴金角大王的Python之路,Day4 - Python基础4 (new版)   本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件 ...

  3. 002 html总结

    1.题目 每个HTML文件里开头都有个很重要的东西,Doctype,知道这是干什么的吗? div+css的布局较table布局有什么优点? strong与em的异同? 你能描述一下渐进增强和优雅降级之 ...

  4. Django:django-cors-headers 报错no module named "corsheaders"

    django跨域使用 pip install django-cors-headers 然后在settings文件中加上参数设置 # app配置 INSTALLED_APPS = [ 'django.c ...

  5. 详解 IntelliJ IDEA 配置和启动maven 项目 步骤

    1.本地安装maven 1.1 安装 https://www.cnblogs.com/wkrbky/p/6350334.html?utm_source=itdadao&utm_medium=r ...

  6. vue小技巧之偷懒的文件路径——减少不必要的代码

    众所周知,我们写vue项目的时候都会创建很多个文件,尤其是一些中大型项目,会有很深的文件夹,当你去引入的时候,要写很长的路径比如我要引入一个css文件, 必须得 import  '../../../s ...

  7. PCB差分线学习

    问:何为差分信号? 答:通俗地说,就是驱动端发送两个等值.反相的信号,接收端通过比较这两个电压的差值来判断逻辑状态“0”还是“1”. 问:差分线的优势在哪? 答:差分信号和普通的单端信号走线相比,最明 ...

  8. photoshop改变图片大小,不改变像素

    用画图修改了图片像素,360*440 但是图片30K,要求图片20K 打开photoshop,打开图片,点击文件--存储为web所用格式,调节品质大小到20K以下,保存即可

  9. win10系统盘分多大合适?

    WIN10系统盘分多大合适,想必许多网友在装系统的时候都犹豫不觉吧,不过现在的硬盘基本上都是512G 1T的机械硬盘,固态硬盘基本都是128G以上,256G几乎成为标配,所以WIN10系统盘空间还是足 ...

  10. 如何修改SnipeIT的部分设置

    作为一款开源的资产管理系统,Snipe-IT非常的好用又结实,但是原始设置对中国用户有些不方便,部分汉化没有完成,需要直接修改代码,下面把常用的修改记录如下: 1.修改资产打印标签中的文本名称 找到  ...