博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JVM
阅读量:6294 次
发布时间:2019-06-22

本文共 2714 字,大约阅读时间需要 9 分钟。

一、走近Java

Java是一门结构严谨、面向对象的编程语言。摆脱了硬件平台的束缚,实现了一次编写,到处运行的理想;提供了一个相对安全的内存管理和访问机制,避免了绝大部分的内存泄漏和指针越界问题;实现了热点代码检测和运行时编译及优化,这使得Java应用能随着运行时间的增加而获得更高的性能。

Java技术体系

Sun官方定义的Java技术体系包括以下几个组成部分
1.Java程序设计语言
2.各种硬件平台上的Java虚拟机
3.Java API类库
4.Class文件格式
5.各商业机构和开源社区的第三方Java类库

Java程序设计语言、Java虚拟机、Java API类库这三部分统称为JDK,JDK是用于支持Java程序开发的最小环境。

Java虚拟机、Java SE API子集这两部分统称为JRE,JRE是支持Java程序运行的标准环境。

Java虚拟机发展史

1.Sun Classic
Sun Classic VM是世界上第一款商用Java虚拟机,已停用。

2.Sun HotSpot VM

Sun JDK和OpenJDK自带的虚拟机,也是目前使用范围最广的Java虚拟机。

3.BEA JRockit/IBM J9 VM

除了Sun公司以外,其它组织、公司也研发过不少虚拟机实现,其中规模最大、最著名的就是BEA和IBM公司。

4.Azul VM/BEA Liquid VM

5.Apache Harmony/Google Android Dalvik VM

6.Microsoft JVM

二、Java内存区域划分
1.堆内存
堆内存用于存放对象实例,在虚拟机启动时创建,被所有线程共享,是Java虚拟机所管理的内存中最大的一块。堆内存是垃圾收集器管理的主要区域,由于现在收集器基本都是采用的分代收集计算法,所以堆内存中可以细分为:新生代和老年代;再细致一点的有Eden空间、From Survivor空间、To Survivor空间等。

2.栈内存

栈内存用于存放局部变量(基本数据类型和对象引用)、操作栈、方法返回等信息。线程私有,生命周期和线程一致。每个方法被执行时,虚拟机都会在栈内存中创建一个栈帧(Stack Frame),每个方法从被调用到执行完毕,就对应着一个栈帧在虚拟机中从入栈到出栈的过程。

3.本地方法栈

本地方法栈与栈内存的作用非常相似,区别在于本地方法栈只为native方法服务。

4.方法区

方法区是多个线程共享的内存区域,用于存放类信息、常量、静态变量、编译后的代码数据。(运行时常量池是方法区的一部分)。

5.程序计数器

程序计数器是一块较小的内存区域,用于引导字节码解析顺序(如分支、循环、跳转、异常处理)。线程私有,各线程之间的计数器互不影响,独立存储。

三、垃圾收集器与内存分配策略
垃圾收集(Garbage Collection,GC)
栈内存、本地方法栈、程序计数器的生命周期和线程一致,当方法结束或线程结束时,内存就回收了。而堆内存和方法区则不一样,一个方法中多个分支需要的内存可能不一样,只有在程序处于运行期间才知道会创建哪些对象,这部分内存的分配和回收都是动态的,垃圾收集器所关注的就是这部分内存。

垃圾收集算法

1.标记-清除算法
2.复制算法
3.标记-整理算法
4.分代回收算法

垃圾收集器

1.Serial收集器
2.ParNew收集器
3.Parallel Scavenge收集器
4.Serial Old收集器
5.Parallel Old收集器
6.CMS收集器
7.G1收集器

四、虚拟机性能监控与故障处理工具
1.jdk的命令行工具
jps 显示虚拟机的进程状况
jstat 显示虚拟机中各种运行状态信息,如类装载、内存、垃圾收集、JIT编译等
jinfo 显示虚拟机的配置信息
jmap 用于生成堆转储快照(一般称为heapdump或dump文件)
jhat 与jmap搭配使用,来分析jmap生成的堆转储快照
jstack 用于生成当前线程正在执行的方法中堆栈的集合

2.jdk的可视化工具

2.1.JConsole:Java监视与管理控制台
2.2.VisualVM:多合一故障处理工具

五、调优案例分析

六、类文件结构
计算机只认识0和1,所以我们写的程序需要经编译器翻译成由0和1构成的二进制格式才能由计算机执行。

七、虚拟机类加载机制
虚拟机把class文件加载到内存,并对数据进行验证、准备、解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。

类的生命周期:加载、验证、准备、解析、初始化、使用、卸载。

加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,而解析阶段则不一定,它在某些特定情况下可以在初始化之后再开始。

类加载的过程

类加载的过程包括加载、验证、准备、解析和初始化5个阶段。
1.加载
加载阶段,虚拟机需要完成3件事:
a.通过一个类的全限定名来获取定义此类的二进制字节流。
b.将这个字节流代表的静态存储结构转化为方法区的运行时数据结构。
c.在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据访问入口。

2.验证

验证的目的是为了确保Class文件中字节流包含的信息符合当前虚拟机的要求,并且不会危害虚拟机的自身安全。

3.准备

准备阶段会在方法区给类变量分配内存并设置初始值,其中类变量的初始值为0,常量的初始值为程序设定的值。实例变量将会在对象实例化时随着对象一起分配在Java堆中。

4.解析

解析阶段是虚拟机将常量池中的类、方法、属性替换为可直接引用的过程。

5.初始化

初始化类变量,执行构造器。

虚拟机规范规定了5种情况必须立即对类进行初始化(而加载、验证、准备自然在此之前执行)

1.new操作。
2.反射。
3.当初始化一个类时,如果该类的父类没有进行初始化,则先触发父类的初始化。
4.当虚拟机启动时,用户需要指定一个要执行的主类(包含main方法的那个类)。
5.JDK1.7,java.lang.invoke.MethodHandle。

类与类加载器

类加载器虽然只用于实现类的加载动作,但它在Java程序中起到的作用却远远不限于类加载阶段。对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性。比较两个类是否相等,只有在这两个类是由同一个类加载器加载的前提下才有意义。

 

转载于:https://www.cnblogs.com/lc19149/p/9389361.html

你可能感兴趣的文章
Android.mk 文件语法详解
查看>>
QT liunx 工具下载
查看>>
内核源码树
查看>>
AppScan使用
查看>>
Java NIO框架Netty教程(三) 字符串消息收发(转)
查看>>
Ucenter 会员同步登录通讯原理
查看>>
php--------获取当前时间、时间戳
查看>>
Spring MVC中文文档翻译发布
查看>>
docker centos环境部署tomcat
查看>>
JavaScript 基础(九): 条件 语句
查看>>
Linux系统固定IP配置
查看>>
配置Quartz
查看>>
Linux 线程实现机制分析
查看>>
继承自ActionBarActivity的activity的activity theme问题
查看>>
设计模式01:简单工厂模式
查看>>
项目经理笔记一
查看>>
Hibernate一对一外键双向关联
查看>>
mac pro 入手,php环境配置总结
查看>>
MyBatis-Plus | 最简单的查询操作教程(Lambda)
查看>>
rpmfusion 的国内大学 NEU 源配置
查看>>