一、java语言

1.1 支持面向对象编程oop

强调支持,因为java同样可以面向过程编程。

oop的三大特性是:封装、继承、多态。

封装主要针对成员变量而言,oop的思想要求成员变量均为私有,不应该对外能够访问,一个符合oop思想的类应该只有公共方法对外能够访问;

继承,主要理解继承体系,private、protected、public在继承中的使用场景。理解java是单继承多实现的(与C++的区别);

多态主要指一个类的实例是运行时决定的,而不是声明时决定的。父类 a = new 子类();是可以的。这种作用在于可以面向抽象编程、面向接口编程,对象不必必须和声明的类一致,只要是它的子类、孙子类等即可;

1.2 jdk版本对java语言的改进

1996年发布jdk1.0,java语言具备基础的oop语法;

1997年发布jdk1.1,引入内部类;

2004年发布jdk1.5,引入语法糖,自动拆装箱、泛型、动态注解、枚举、可变长参数、遍历循环(foreach);

2014年发布jdk8,引入Lambda表达式;

二、jvm虚拟机(本文特指官方默认的HotSpot虚拟机)

2.1 发展

由一家小公司Longview Technologies开发出来,1997年被sun公司收购,jdk1.3之后正式成为官方默认虚拟机;

HotSpot得名来自于其热点代码探测技术,可以有效的把热点代码探测出来,并利用JIT编译器将热点代码进一步优化并编译成机器代码,提高运行效率;

2.2 jvm虚拟机的内存区域组成

程序计数器,线程私有,指向字节码指令;

java虚拟机栈,线程私有,主要就是描述java方法的,配合程序计数器一起一步一步往下执行方法(理解为什么是栈);

本地方法栈,线程私有,跟java虚拟机栈类似,区别是它用来执行非java方法;

java堆,线程共享,这是最大的一块虚拟机内存区域,主要就是我们new的对象都会分配在这里,这里分为新生代(Eden、Survivor1、Survivor2)和老年代;

方法区,线程共享,在HotSpot里叫永久代(Permanent Generation),存放加载的类信息、常量、静态变量等,static代码块、static变量、static方法都会存放在这里有一个副本。为什么叫永久代,主要是对这部分的对象实例回收的效率不高,这部分对象实例存活率较高;

运行时常量池,是方法区的一部分;

直接内存,不是虚拟机内存的一部分,指申请虚拟机内存外的内存。

2.3 垃圾收集算法

怎么样判断对象可以回收?有引用计数算法和可达性分析算法。引用计数算法很简单,给每个对象一个引用计数器,每当有一个地方引用了它,那么就给它计数器+1,当这个引用失效之后计数器-1,这样做非常高效,但有一个缺陷是互相引用的对象,无法被回收,造成内存泄露。HotSpot使用可达性分析算法,可达性分析算法从GC Roots对象是否可达来判断对象是否可以回收,GC Roots对象包括虚拟机栈引用的对象、方法区类静态属性引用的对象、方法区常量引用的对象、本地方法栈中引用的对象;

IBM研究指出98%的对象都是朝生夕死,故新生代中回收频率要较高,每次可以回收大量内存,老年代中经过两次以上的回收仍存活,说明回收的效率不高,回收频率可以低一点。另外,大对象不在新生代中分配,而是直接进入老年代。

①标记-清除算法。算法的思想是首先把需要回收的对象标注出来,然后统一清除回收。实现起来很简单,但标记和清除的效率不高,还会产生大量不连续的内存空间,影响后续为新对象分配内存,尤其是大对象。

②复制算法。针对标记-清除算法的问题,复制算法的思想是把内存区域均等的分成两块,比如10M的内存均等分为两块5M,每个时刻只能使用一块,先从第一块标记仍存活对象的对象,然后统一复制到第二块内存中,并按内存空间顺序排好,第一块内存则全部回收。第二次回收时就先从第二块开始,循环往复。这样做效率很高,并且内存空间可以连续分配。但造成一个问题是本来10M的内存只能用一半,造成内存的浪费。

HotSpot在实际实现复制算法时,将内存空间划分为Eden和两个Survivor,且默认Eden和Survivor的比例是8:1:1,新对象分配在Eden中,第一次回收后存活对象被复制到Survivor 1中,Eden全部清除,第二次新对象仍分配在Eden中,第二次回收时Eden和Survivor 1中存活对象被复制到Survivor 2中,Eden和Survivor 1全部清除。

这里有一个问题:如果存活对象超过内存的10%怎么办?这时候就需要从老年代中进行分配担保(Handle Promotion)。

③标记-整理算法。和新生代不同,在老年代中GC回收的效率不会太高,使用复制算法Survivor空间很可能是不够的,如果将Survivor调大又浪费内存空间,这时就提出了标记-整理算法应对老年代的实际情况。标记-整理算法内存回收时先将所有存活对象标记出来,但不进行清除,而是将存活对象都往内存的一端移动,那么内存末端都是可回收的对象,当这些可回收对象被“挤出”内存边界的时候,则被清除了。

由于HotSpot中把java堆中分为新生代、老年代,他们存活的几率不一样,所以按新生代和老年代采取不同的算法,这就叫分代收集算法,在新生代中采取复制算法,在老年代中使用标记-清除或标记-整理算法。

2.4 垃圾收集器

上面分析了新生代、老年代应该采取怎样的算法,HotSpot中针对实际应用场景,实现了不同的垃圾收集器;

①Serial收集器,复制算法,单线程,Client模式下默认新生代收集器。会有Stop The World问题;

②ParNew收集器,复制算法,多线程,新生代收集器;

③Parallel Scavenge收集器,复制算法,多线程,新生代收集器,与ParNew的区别在于它针对吞吐量设计的;

④Serial Old收集器,标记-整理算法,单线程,Client模式下默认老年代收集器;

⑤CMS收集器,标记-清除算法,多线程,老年代收集器,以降低停顿时间为目标,只在初始标记、重新标记的时候需要Stop The World,采取并发标记和并发清除降低停顿时间;

⑥G1收集器,标记-整理算法+复制算法,多线程,老年代收集器;

三、编译与运行

3.1 javac编译器编译

第一次编译,将.java文件编译成中间语言,输出.Class文件,这期间主要完成语法分析和词法分析(编译原理)、注解处理、语义分析(解语法糖等)、生成字节码Class文件;

3.2 解释器

类加载进解释器运行,类加载的过程有:加载、验证、准备、解析、初始化;

3.3 JIT即时编译器

解释器监控热点代码为JIT编译器进一步编译提供监控数据,触发JIT编译器将热点代码编译成机器代码;

本人知识水平有限,文章难免有纰漏之处,请不吝纠正勘误。

java语言与jvm虚拟机简介的更多相关文章

  1. 深入理解java:1. JVM虚拟机的构成

    1.JVM虚拟机的构成 什么是Java虚拟机? 作为一个Java程序员,我们每天都在写Java代码,我们写的代码都是在一个叫做Java虚拟机的东西上执行的. 但是如果要问什么是虚拟机,恐怕很多人就会模 ...

  2. java语言体系的技术简介之JSP、Servlet、JDBC、JavaBean(Application)

    转自:https://zhangkunnan.iteye.com/blog/2040462 前言 Java语言 Java语言体系比较庞大,包括多个模块.从WEB项目应用角度讲有JSP.Servlet. ...

  3. 【Java杂货铺】JVM#虚拟机加载机制

    代码编译的结果从本地机器码变为字节码,是储存格式发展的一小步,却是编程语言发展的一大步--<深入理解Java虚拟机> 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转化 ...

  4. Java语言与JVM中的Lambda表达式全解

    Lambda表达式是自Java SE 5引入泛型以来最重大的Java语言新特性,本文是2012年度最后一期Java Magazine中的一篇文章,它介绍了Lamdba的设计初衷,应用场景与基本语法. ...

  5. 探索Java语言与JVM中的Lambda表达式

    Lambda表达式是自Java SE 5引入泛型以来最重大的Java语言新特性,本文是2012年度最后一期Java Magazine中的一篇文章,它介绍了Lamdba的设计初衷,应用场景与基本语法.( ...

  6. Java 如何得到 JVM 虚拟机的 System Properties

    Java 6 jps 命令得到进程号 jinfo -sysprops <PID> > sysprops.txt 打开 sysprops.txt 就可以查找 Language Time ...

  7. [零] Java 语言运行原理 JVM原理浅析 入门了解简介 Java语言组成部分 javap命令使用

    Java Virtual Machine  官方介绍 Java虚拟机规范官方文档 https://docs.oracle.com/javase/specs/index.html 其中以java8的为 ...

  8. Java语言简介、基础组成、封装、继承、多态、抽象类、内部类、接口

    目录 Java简介 Java语言基础组成 面向对象 对象 封装 构造函数 this关键字 static(静态关键字) 主函数 静态什么时候用呢? 面向对象(数组工具对象建立) 设计模式 继承 成员变量 ...

  9. [Java入门笔记] Java语言简介

    前言 学习Java有一段时间了,但是一直缺少一个系统的思想,现在重新通过书籍中.网上的文章,视频等资料,整理与回顾Java的知识点. 言归正传,让我们先从了解Java语言开始. Java语言的由来 J ...

随机推荐

  1. 使用nuget打包类库并发布

    前言 NuGet 是免费.开源的包管理开发工具,专注于在 .NET 应用开发过程中,简单地合并第三方的组件库.今天的目的就是记录一下如何打包一个类库,并发布到官网.在开始之前需要在www.nuget. ...

  2. codeacademy

    codeacademy http://link.zhihu.com/?target=https%3A//www.youtube.com/playlist%3Flist%3DPLP6DbQBkn9ymG ...

  3. 【转】Github轻松上手4-常用的git命令

    转自:http://blog.sina.com.cn/s/blog_4b55f6860100zzih.html 附上一些git的常见命令: •    git remote add origin git ...

  4. OpenShare文档管理不完整功能清单

    文档结构管理 以网站集-网站的方式建立各部门的文档管理中心,让文档管理更加规范,使用户更加方便地进行浏览.查找和使用文档资源. 文档全生命周期管理 结合定制开发的工作流平台对文档的全生命周期(创建.获 ...

  5. 团队自动化环境搭建与管理--php博弈

    我是方少,很开心与大家日后与大家交流技术上面的一些想法和一些业务上的分享.以前从来没写过博客,因为觉得不重要吧,如今觉得有必要沉淀一些想法和回忆.好了费话不多说. 先上图: 业务问题:在每次新伙伴加入 ...

  6. RxJava 复杂场景 Schedulers调度

    参考: https://blog.piasy.com/2016/10/14/Complex-RxJava-2-scheduler/ 以Zip为例,学习Schedulers的线程调度 要求: * cre ...

  7. ROW_NUMBER() OVER 排序函数的基本用法

    ROW_NUMBER() OVER 排序函数 select ROW_NUMBER() OVER (PARTITION BY guide_id ORDER BY pic_sort) as rowid,p ...

  8. LIS 最长递增子序列问题

    一,    最长递增子序列问题的描述 设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1< ...

  9. c#基础,单线程,跨线程访问和线程带参数

    using System; using System.Collections.Generic; using System.Threading; using System.Windows.Forms; ...

  10. Java架构师技能发展脑图

    图中还有好多东西不会,先把图保存好,逐项击破