一.JVM的出现

  1. JVM将字节码解释成不同os下的机器指令,有了jvm,java语言在不同平台上运行时不需要重新编译
  2. 虚拟机发展史
    (1)Sun Classic

    1. classic jvm要么采用纯解释器解释执行,要么采用JIT编译执行,一旦JIT进行编译执行,则解释器不再生效
    2. 如果使用JIT编译代码,则JIT会对每个方法,每行代码都进行编译,对于那种只需运行一次,不具有编译价值的代码,也会被JIT编译执行。迫于程序响应时间的压力,此阶段的JIT不敢采用编译耗时的优化技术,所以及时采用JIT输出本地代码,他的执行效率也和C代码有很大差距。被人诟病“java语言很慢”

    (2)Exact VM

    1. Exact VM进入了高性能虚拟机时代,开始使用编译器解释器混合模式
    2. Exact VM使用了精确式内存管理,他能判定内存中摸个位置的数据具体是什么类型。eg:内存中有一个数是12345,ExactVM可以判断他是一个int数字,还是一个指向内存12345地址的引用。这种精确式内存管理,在gc时,可以直接回收引用类型的数据,少了像classic vm时代gc时的数据类型查找过程

    (3)HotSpot虚拟机

    1. Hot Spot是当前jdk采用的虚拟机 (1.4以后)
    2. 热点代码探测技术:通过计数器找出最具编译价值的代码,通知JIT以方法为单位进行编译。如果方法被频繁调用,则触发标准编译;如果方法中循环次数很多,触发栈上替换编译动作。
    3. HotSpot无需等待本地代码输出后才能执行程序,使得即时编译压力减小,有助于采用更更多的代码优化技术。输出高质量的操作系统本地代码

二. JVM运行时数据区域

  1. 线程隔离的数据区
    (1)程序计数器:

    1. 字节码的行号指示器。解释器根据程序计数器选取要执行下条指令。分支,循环,跳转,异常处理,线程恢复等基础功能都需要程序计数器来完成。
    2. 为了线程切换后能继续执行正确的代码,每条线程都要维护自己的程序计数器,各个线程间的程序计数器互不影响
    3. 如果线程执行的是native方法,则该线程的程序计数器值为空

    (2)虚拟机栈:

    1. 虚拟机栈用来执行java方法
    2. 每个java方法执行的时候都会创建一个栈帧。栈帧用来存储局部变量表,操作数栈,动态链接,方法出口等信息。

    (3)本地方法栈

    1. 本地方法栈用来执行native方法
  2. 线程共享数据区
    (1)java堆

    1. java堆存储对象实例
    2. java堆分为新生代和老年代。新生代分为eden,from survive,to survive空间

    (2)静态区

    1. 静态区也叫做永久带,存放类信息,常量池,静态变量,JIT编译后的代码等。
    2. 常量池技术:为了方便创建一个对象二出现的。当需要创建一个对象时,如果常量池中有该对象,则直接从池子中取出来,在重复创建相等变量时节省了很多时间。eg:str1=“abc”,str2=“abc”。这样直接声明的字符串会放到常量池中,所以str1和str2是静态区常量池中的同一块内存地址

三. JVM的4中引用

  1. 强引用:new对象。其他引用方式都实在强引用失效(置成null后才有用)
  2. 软引用
    (1)一个对象被强引用new出来以后,在jvm中,可以存在软引用
    (2)对象=null使得强引用失效后,如果对象还存在软引用,则引用的对象在gc时不会被垃圾回收。只有当jvm发生内存溢出前,软引用引用的对象才被回收。因此,软引用可以被当做缓存
    ```java
    Person p = new Person();
    SoftReference softReference = new SoftReference<>(p);

    p = null; // 断开强引用
    System.gc();
    System.out.println(softReference.get().getName()); // 输出aaa
    ```

  3. 弱引用
    触发gc时,就会被当做垃圾回收。若引用的生命周期是强引用失效后,到gc触发时
    ```java
    Person p = new Person();
    WeakReference reference = new WeakReference<>(p);

     p = null;   // 断开强引用System.out.println(reference.get().getName());  // 输出aaaSystem.gc();System.out.println(reference.get().getName());  // 抛出nullexception

    ```

  4. 幽灵引用
    幽灵引用和没有引用一样,对象的生命周期和只有强引用时一样。只是在对象被回收时会收到一个系统通知
    ```java
    Person p = new Person();
    ReferenceQueue referenceQueue = new ReferenceQueue<>();
    PhantomReference reference = new PhantomReference<>(p,referenceQueue);

     p = null;   // 断开强引用try{System.out.println(reference.get().getName());  // 抛出nullpointer Exception}catch (Exception e){e.printStackTrace();}System.gc();try{System.out.println(reference.get().getName());  // 抛出nullpointer Exception}catch (Exception e){e.printStackTrace();}

    ```

【注】:软引用和若引用都延长了对象引用的生命周期,一个延长至oom发生,一个延长至gc发生时。幽灵引用只是提供对象gc的通知
ThreadLocal使每个线程保存各自的变量副本,值得注意的是,这个变量要在每个线程内部初始化,因为ThreadLocal不会生成变量副本,如果在线程外初始化变量,仍然有线程安全问题

转载于:https://www.cnblogs.com/72808ljup/p/5348475.html

一. JVM发展史,运行时数据区域,四大引用相关推荐

  1. 【深入理解JVM】运行时数据区域:java虚拟机栈

    虚拟机栈是线程私有,生命周期与线程相同. java虚拟机栈描述的是Java方法执行的线程内存模型: 每个方法在执行的时候,Java虚拟机栈都会同步创建一个栈帧(stack frame),用于 储存 局 ...

  2. 12.JDK1.8 JVM运行时数据区域概览、各区域介绍、程序计数器、Java虚拟机栈、本地方法栈、堆、堆空间内存分配(默认情况下)、字符串常量池、元数据区、jvm参数配置

    12.JDK1.8 JVM运行时数据区域概览 12.1.JDK1.8 JVM运行时数据区域概览 12.2.各区域介绍 12.3.各区域介绍 12.3.1.程序计数器 12.3.2.Java虚拟机栈 1 ...

  3. JVM学习笔记:Java运行时数据区域

    JVM执行Java程序的过程中,会使用到各种数据区域,这些区域有各自的用途.创建和销毁时间.根据<Java虚拟机规范>,JVM包括下列几个运行时数据区域,如下图所示: 其中红色部分是线程私 ...

  4. [jvm]运行时数据区域详解

    了解虚拟机是怎么使用内存的,有助于我们解决和排查内存泄漏和溢出方面的问题.详解java虚拟机内存的各个区域,分析这些区域的作用服务对象以及可能发生的问题. 一.运行时数据区域 java虚拟机在执行ja ...

  5. JVM学习笔记② JVM运行时数据区域

    JVM所管理的内存将会包括以下几个运行时数据区域: 方法区(Method Area) 方法区是各个线程共享的区域,存放类信息.常量.静态变量.即时编译器编译后的代码等数据.虽然Java虚拟机规范把方法 ...

  6. Java JVM内存模型(运行时数据区域)详解

    详细介绍了JVM运行时数据区域,包括方法区.堆空间.栈空间.本地方法栈.程序计数器.常量池.直接内存.字面量.符号引用.直接引用. Java程序在运行时,需要在内存中的分配空间.为了提高运算效率,ja ...

  7. JVM运行时数据区域——为什么jdk8用元空间替换了永久代

    以局部窥全局,这个问题其实很复杂,要弄清楚这个问题,首先要对JVM运行时数据区域划分以及各个数据区域的作用了和指掌. JVM运行时数据区域总览 JVM在执行Java程序的过程中(简称运行时)会把它所管 ...

  8. Java 运行时数据区域,哪些是线程隔离的?哪些又是公有的?

    来自:会点代码的大叔 JVM 运行时数据区域大致可以分为:程序计数器.虚拟机栈.本地方法栈.堆区.元空间.运行时常量池.直接内存等区域:就是下面这个样子的: 其中有些区域,随着 JDK 版本的升级不断 ...

  9. Java 运行时数据区域

    运行时数据区域 Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁时间.以下是 Java 虚拟机所管理的内存区域: 程序 ...

最新文章

  1. 机器视觉-相机内参数和外参数
  2. 办公电脑安装虚拟机基本就绪
  3. wdcp3.2.6版 https全站跳转 标记待细化
  4. 首尾连接的数组的求和问题
  5. oracle segments,tablespace,and data files
  6. uml识别事件表格_LOPA分析:使能条件和修正因子在场景识别方法中的应用
  7. JZOJ 5397. 【NOIP2017提高A组模拟10.6】Biology
  8. 如何使用代码给product创建distribution chain
  9. 计算机管理与维护实践课程,天津2012年自考“计算机维护维修(实践)”课程考试大纲...
  10. python3函数调用时间_Python3 time clock()方法
  11. 人工神经网络心得体会_卷积神经网络学习心得
  12. sonarqube 启动不了,异常提示:远程主机强迫关闭了一个现有的连接
  13. Linux通过文件大小查找,linux 根据文件大小查找文件
  14. 计算机编程嘉兴,嘉兴自学电脑编程一对一
  15. 【云小课】基础服务第25课 容灾演练:平时多练兵,急时保可用!
  16. PCL Lesson1 :PCL库PCLVisualizer的简单使用
  17. 扩展IQueryable实现属性名称排序
  18. 用vbs写九九乘法表
  19. 广义线性模型(GLM)及其应用
  20. 如何删除WORD中的空白行

热门文章

  1. 高级排序之快速排序(分割与整合)
  2. win10安装tomcat9
  3. Python数据挖掘 环境搭建
  4. 从下往上看--新皮层资料的读后感 第一部分:皮层细胞
  5. Ubuntu16.04下部署 nginx+uwsgi+django1.9.7(虚拟环境pyenv+virtualenv)
  6. iOS9 Error Domain=NSURLErrorDomain Code=-1022 App Transport Security (ATS)
  7. Failure [INSTALL_FAILED_OLDER_SDK] [每件问题100块]
  8. JavaScript汉字Unicode编码相互转换
  9. python中随机生成数字生成对了是猜对了_python入门(一) 一个猜随机数小游戏...
  10. JavaScript中charAt函数