当前位置: 首页 > news >正文

做网站付多少定金优化seo厂家

做网站付多少定金,优化seo厂家,从手机上可以做网站吗,门户网站推广方式开启新的篇章。 进入JVM啃大瓜系列~~ 目录什么是JVM程序的编译执行过程类的生命周期1、加载类Test(Load the Class Test)2、链接Test类: 检验、准备 、解析((可选) Link Test: verify、prepare、resolve3、 初始化Test…

开启新的篇章。 进入JVM啃大瓜系列~~

目录

  • 什么是JVM
  • 程序的编译执行过程
  • 类的生命周期
    • 1、加载类Test(Load the Class Test)
    • 2、链接Test类: 检验、准备 、解析((可选) Link Test: verify、prepare、resolve
    • 3、 初始化Test类: 执行初始化构造器
    • 4、 执行 Test.main方法
    • 5、 卸载
  • JMM内存模型
    • JMM模型下的线程间通讯
  • volatile
    • 原子性与非原子性
    • volatile原理
  • 参考文献

什么是JVM

要了解什么是JVM,就必须提及JDK。
我们都知道Java具有跨平台的特点,一次编译,到处运行。其可移植性就是基于JDK实现的。
JDK包括JVM屏蔽操作系统差异的组件

  1. 各个操作系统的JVM是一样的
  2. 屏蔽操作系统差异的组件,在各个PC上各不相同。作用是将相同操作对应到不同操作系统的不同操作指令上。

因此不同系统版本的JDK的差异主要是 屏蔽操作系统差异的组件。

程序的编译执行过程

在这里插入图片描述

在这里插入图片描述

类的生命周期

JVM执行java文件的过程包括: 加载类 > 链接 > 初始化 > 使用 > 卸载

1、加载类Test(Load the Class Test)

最初执行类Test的main方法时,当在JVM中发现没有包含这个类的二进制表示时,JVM会使用类装载器(class loader)尝试查找这样的二进制(class文件)表示文件。如果这个过程失败,便会抛出错误(error)。
通俗地来说,就是讲将硬盘中的class 文件加载到JVM内存中。

2、链接Test类: 检验、准备 、解析((可选) Link Test: verify、prepare、resolve

在加载Test之后,必须在调用main方法之前初始化Test类。在初始化前,Test必须进行链接。链接包括以下三部分:

检验(verification): 检验过程使用一张正确的符号表(a symbol table)检查是否合乎Java编程语言、JVM的语义规范。如果在检验阶段检查到问题,就会抛出错误(error)。 通俗地将,校验阶段就是进行语义性校验。

准备(preparation)
准备工作包括静态存储(static storage)的分配并赋予初始默认值(比如static int num = 24; 会在准备阶段将num赋值为0)和 java虚拟机内部使用的任何数据结构,比如方法表。

解析(Resolution)
解析是检查从Test类到其他类和接口的符号引用的过程。通过加载在Test中提到的其他类和接口,并且检查其引用是否 正确。
一种实现是只有当符号引用被主动使用时,才会去加载它。这是解析的懒惰形式。如果Test类有其他类的符号引用,那么引用只在被使用时才被解析,如果不用到则不解析。

通俗地讲,该阶段就是把类中的符号引用转为直接引用
举个栗子:
在前期阶段,还不知道类的具体内存地址,就是用符号"com.johnny.polo.Studnet"代替Student类。此时"com.johnny.polo.Studnet"就称为符号引用。
到了解析阶段,JVM就可以将"com.johnny.polo.Studnet"映射成实际的内存地址,之后急用内存地址来代替Student,这种使用内存地址来使用类的方法叫做直接引用。

3、 初始化Test类: 执行初始化构造器

只有类被初始化了才允许执行该类的main方法。
初始化包括按文本顺序执行的所有类变量的初始化器(class variable initializers)和Test类静态初始化器(static initializers)。 但是在Test类被初始化前,其直接或间接父类都要被初始化。
如果类Test拥有另一个类Super作为其父类,那么Super必须在Test之前初始化,这需要装载、验证和准备Super,还可能涉及递归来解析Super的符号引用。
例如:
static int num = 24;在链接的准备阶段,会将num 赋值为 0。然后在初始化阶段会将0修改为24;

4、 执行 Test.main方法

使用:对象的初始化、对象的垃圾回收、对象的销毁

5、 卸载

类生命周期结束的时机

  1. 正常结束:即JVM将类卸载出运行时数据区域
  2. 程序发生异常或错误,jvm被强行终止。
  3. 程序使用了System.exit)()
  4. 操作系统发生了异常。JVM运行于操作系统之上。操作系统发生了异常,jvm自然也执行不下去。

JMM内存模型

JMM内存模型从另外角度去分析JVM的内存。
在这里插入图片描述

JMM模型下的线程间通讯

线程间的通讯必须通过主内存。如果线程B想与线程A进行通信的话:必须经历一下两个步骤:

  1. 线程B将工作内存中更新过的共享变量刷新到主内存去。
  2. 线程A到主内存中去读取线程B已经更新过的共享变量。

具体通过以下8中操作来实现:
1、Lock: 将主内存变量标识为一条线程A独占
2、 Read: 将主内存中的num读入到工作内存中。
3、 Load: 将2中读取的变量拷贝到工作内存的变量副本中。
4、 Use: 把工作内存中的变量副本传递给线程去使用。
5、 Assign: 把线程中正在使用的变量,传递给工作内存中的变量副本。
6、 Store:将工作内存中的变量副本传递到主内存中。
7、 Write: 将变量副本作为主内存中的一个变量进行存储。
8、 UnLock: 解除线程的独占状态。
在这里插入图片描述

JVM要求上述8个操作必须是原子性的。但是对于64位的数据类型(double/long)有些非原子性协议。因此可能会出现只读取 (写入)半个数据的情况。解决方案:
1、 商用JDK已经解决了上述原生态JDK的问题。
2、 使用volatile 关键字解决。

volatile

volatile 是JVM提供的轻量级的同步机制。
作用:
1、 防止JVM对long/double等64位非原子性协议进行的误操作。
2、 可以使变量对所有的线程立即可见。(如果某一线程修改了工作内存中的变量副本,那么加上volatile之后,该变量就会立刻同步到其他线程的工作内存中)
3、 禁止指令的“重排序”优化

原子性与非原子性

提到重排序,就必须先了解原子性操作和非原子性操作。原子性操作例如num = 10;非原子性操作例如int num = 10;该语句会被 拆分成int num; num = 10;两条语句执行。
而重排序的对象就是原子性操作,目的是为了提高执行效率,是JVM的优化。

int a = 10; //1
int b;  //2
b = 20; //3
int c = a * b; // 4

重排序不会影响单线程的执行结果。因此上述程序在经过重排序之后,可能的执行结果是1,2,3,4或者2,3,1,4

但是这样的优化有时也会带来
一些不想要的效果。

/***  双重检查式的懒汉式单例模式*/
public class Singleton {private static Singleton instance = null;private Singleton(){ }private static Singleton getInstance(){if( instance == null){synchronized(Singleton.class){if( instance == null){instance = new Singleton();}}}return instance;}}

上述代码可能会出现问题,原因是instance = new Singleton() 不是一个原子性操作,会在执行时拆分成以下动作
1、 JVM会分配内存地址、内存空间。
2、 使用构造方法实例化对象
3、 instance = 第1步分配好的内存地址

根据重排序知识,上述动作的执行顺序可能是1,3,2。如果此时是多线程操作,当A线程执行完1、3,然后B线程进入该方法,由于线程A已经为该对象分配了内存地址, instance != null,会直接返回instance对象。此时如果线程B使用该对象的方法则必然会报错。
解决方案是*禁止1,3,2的重排序,在对象引用加上volatile修饰即可

    private static volatile Singleton instance = null;

volatile原理

volatile是通过“内存屏障”防止重排序问题
1、 在volatile写操作前,插入StoreStore屏障
2、 在volatile写操作后,插入StoreLoad屏障
3、 在volatile读操作前,插入LoadLoad屏障
4、 在volatile读操作后,插入LoadStore屏障

注意: volatile 不能保证原子性、线程安全 如果想要保证原子性,

验证如下:

public class TestVolatile {static volatile int num = 0;public static void main(String[] args) throws InterruptedException {//创建100个线程 每个线程执行num加3000次1for(int i = 0; i < 100; i ++){new Thread(() -> {for(int j = 0; j< 3000;j ++)num ++;}).start();}Thread.sleep(1000);System.out.println(num);}
}

原先如果是线程安全,则结果应该是30 0000,但答案是206721。说明volatile 并不能保证线程安全。
原因是num ++并不是一个原子操作。 num++被拆分成两个动作:①、 num + 1, ②、 num =①的结果。
要想保证原子操作,可以使用java.util.concurrent.atomic包中的类,该类能保证原子性的核心在于提供了compareAndSet()方法,该方法提供了cas算法(无锁算法)。

参考文献

JVM 文档阅读
周志民 《深入理解java虚拟机》

http://www.lbrq.cn/news/2794915.html

相关文章:

  • 工作是套模板做网站北京seo加盟
  • 怎么做自动提卡网站常德政府网站市民留言
  • 做网站维护价格今日足球比赛分析推荐
  • 渭南市建网站产品线下推广方式都有哪些
  • 大余网站帮我搜一下长沙做网络销售
  • 做网站需要看那几点排名优化公司口碑哪家好
  • 网站备案未注销 影响网站如何优化推广
  • wordpress h5制作插件武汉整站优化
  • 用照片做的ppt模板下载网站淘数据
  • 重庆网站推广机构衡水seo营销
  • 电商网站设计规划书seo网站排名优化教程
  • 安徽建网站公司怎样优化关键词到首页
  • 网站怎么做隐藏内容谷歌优化seo
  • wordpress 用户权限分配seo网络营销课程
  • 潍坊哪家做网站做的最好竞价托管推广
  • 上传设计作品的网站郑州网站优化推广
  • 专业网站建设服务报价百度站长工具验证
  • 垦利网页定制seo网站推广计划
  • 青岛 网站维护关键字
  • 怎么做网站内部搜索功能软文广告示范
  • wordpress下拉南宁网站运营优化平台
  • 织梦可以做婚纱影楼网站吗免费seo
  • 网站定制型和营销型广点通和腾讯朋友圈广告区别
  • asp网站qq登录太原seo外包平台
  • 建设购物网站论文网站alexa排名查询
  • 营业推广谷歌seo外链
  • 刚创业 建网站中国新闻今日头条
  • 音乐网站用dw怎么做网络营销比较常用的营销模式
  • 网页设计与网站建设课程报告百度最怕哪个投诉电话
  • 小狗做爰网站搜索引擎提交入口网址
  • 遥感机器学习入门实战教程|Sklearn案例⑤:集成学习方法全览
  • imx6ull-驱动开发篇30——Linux 非阻塞IO实验
  • 点大餐饮独立版系统源码v1.0.3+uniapp前端+搭建教程
  • 瑞萨e2studio:HardwareDebug配置项详解
  • Python 面向对象三大特性详解(与 C++ 对比)
  • 【LeetCode 热题 100】198. 打家劫舍——(解法二)自底向上