JVM(1)——简介
网上流传着一段挺有意思的话……
对于从事C或C++的开发人员来说,他们既是内存管理的最高权力的皇帝,也是最基础的劳动人民,担负着每一个对象生命开始到终结的维护工作,有点光杆司令的赶脚。
但对于java程序员来说,在虚拟机自动内存管理机制的帮助下,不需要手动维护,也不容易出现内存泄漏和溢出的问题。但是如果不了解JVM,一旦出现问题,你就会变得无从下手……
一、JVM
Java Virtual Machine(java虚拟机),一种虚构的计算机,通过在实际计算机上模拟各种计算机功能实现的。
JVM结构基本上由三大部分组成:类加载器(ClassLoader subsystem),执行引擎(Execution Engine),内存区(Runtime data areas)。
1、类加载器
在JVM启动或类运行时将需要的class字节码(下图的*.class文件)加载到JVM中。
初始类加载器有三个层次:根类、扩展类和系统类加载器。
1)Bootstrap ClassLoader(根类)
2)Extension ClassLoader
3)System ClassLoader
2、执行引擎
负责执行class文件中的指令,得到执行结果。
本质是执行一个个方法串起来的流程,对应操作系统中的一个java线程。
3、内存区
在执行引擎执行前、执行中,都需要存储一些东西,这就用到了java的内存管理,他将内存划分为若干区来模拟实际机器上的存储、记录和调度功能模块。
具体的内存管理内容下面再介绍。
二、工作原理
java语言的跨平台性离不开JVM的作用,下图是编译执行的简化过程。JVM屏蔽了各个计算机平台相关的软件或硬件之间的差异,使得java不需要再考虑平台不同的问题,直接交给JVM就可以了。
三、内存区域
在java虚拟机规范中将java运行时数据划分为以下几种:
1)线程共享
即上图左侧蓝色内容,这两块内容是线程共享的,而不是线程私有的。
堆
堆是储存对象实例的地方,几乎所有的对象实例都是在这里分配的,是JVM管理对象的核心存储区域。
因为在栈中存储的变量等数据都是随线程或方法结束而消失的,但堆中并不是这样,再加上对象实例一般占用内存也比较大,因此Java堆是垃圾收集器管理的主要区域,有时也被成为“GC堆”Garbage Collected Heap。
在实际回收的过程中,如果每次回收都将堆中的对象实例“检查”一遍,看是不是需要回收的话,这样效率太慢了,执行起来太费事了。现在流行的分代收集算法就解决了这一问题,大概意思就是划分出不同的“年代”区域,不同的区域内回收的频率不同,如果多次检查一个实例都不需要释放回收,那我们就把他挪到下一个年代中去。
java堆还可以细分为:新生代和老年代。新生代还可以细分为:Eden、From Survival,To Survival等。详情见下图。
方法区
方法区用于存储类结构信息,包括类信息、常量、静态变量等。在HotSpot虚拟机中,方法区中为“永久代”。因此,垃圾回收器很少光顾这部分区域,这部分比老年代的回收频率更低。
方法区中比较常用的是运行时常量池( Runtime Constant Pool),代表运行时每个class文件中的常量表,位于方法区中。
2)其他
内存区域图中的右侧内容,该部分是线程私有的。
程序计数器
指示当前线程所执行的字节码的行号,但如果执行的native方法,计数器值为空。
很多Native方法都是用C语言实现的,通常叫他C栈,直接放入本地方法栈中执行。
Java虚拟机栈
java栈是线程私有的,每启动一个新线程,java虚拟机就会给他分配一个(以帧为单位的)java栈。他的生命周期和线程相同。执行的操作有两种:压栈和出栈。
四、实例分析
补充了这么多理论知识,是时候该来个例子巩固一下了……
public class Person {
private Integer id;
private String name;
private String password;
public Person(Integer id, String name, String password) {
super();
this.id = id;
this.name = name;
this.password = password;
}
//get和set方法省去
}
//测试类
public class Test {
public static void main(String[] args) {
Test test=new Test();
int id=1;
Person p1=new Person(2,"Sherry","123");
Person p2=new Person(3,"yang","456");
test.change(id);
}
public void change(int i){
i=8;
}
}
Step1:
main()方法是程序的入口,当执行完main方法的前两行代码之后,内存中的情况大致如下图所示:
注意:
图中的“xxx”代表持有引用的地址。
虽然在上面的内存图中,左侧为堆右侧为栈,但为了更清楚的表示引用关系,这里就把栈画在左侧,堆在右侧。
Step2:
执行完第四行代码时
注意:此时test和id的内存块并不会释放,因为对象还未死,或者说引用还在。使用new创建的对象实例保存在堆中,但变量p1、p2在栈中,持有着实例的地址,即图中的“xxx”。
Step3:
第五行代码调用change(),此时需要创建一个新的栈帧。当调用结束之后,变量i的内存块和change()方法的栈帧一并消失。
小结
这篇博客只是对jvm进行了简单的介绍,很多东西只是提了一下,没有深入了解,后续会进行补充和完善。如果哪里理解的不合理,还请交流指正。
JVM(1)——简介的更多相关文章
- 老李分享:jvm结构简介 1
老李分享:jvm结构简介 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:9088214 ...
- 老李分享:jvm结构简介 2
2.2.4 Program counter regsiters:程序计数器 类似于PC寄存器,是一块较小的内存区域,通过程序计数器中的值寻找要执行的指令的字节码,由于多线程间切换时要恢复每一个线程的当 ...
- java语言与jvm虚拟机简介
一.java语言 1.1 支持面向对象编程oop 强调支持,因为java同样可以面向过程编程. oop的三大特性是:封装.继承.多态. 封装主要针对成员变量而言,oop的思想要求成员变量均为私有,不应 ...
- JVM锁简介:偏向锁、轻量级锁和重量级锁
转自:https://www.aimoon.site/blog/2018/05/21/biased-locking/ 比较复杂,简略见另一篇:https://www.cnblogs.com/twohe ...
- JVM性能优化, Part 1 ―― JVM简介
JVM性能优化这些列文章共分为5章,是ImportNew上面翻译自Javaworld: 第1章:JVM技术概览 第2章:编译器 第3章:垃圾回收 第4章:并发垃圾回收 第5章:可伸缩性 众所周知,Ja ...
- Java JVM、JNI、Native Function Interface、Create New Process Native Function API Analysis
目录 . JAVA JVM . Java JNI: Java Native Interface . Java Create New Process Native Function API Analys ...
- Java内存管理-初始JVM和JVM启动流程(二)
勿在流沙住高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 上一篇分享了什么是程序,以及Java程序运行的三个阶段.也顺便提到了Java中比较重要 ...
- 一个性能较好的JVM参数配置
一个性能较好的web服务器jvm参数配置: -server//服务器模式-Xmx2g //JVM最大允许分配的堆内存,按需分配-Xms2g //JVM初始分配的堆内存,一般和Xmx配置成一样以避免每次 ...
- 一个性能较好的JVM参数配置(转)
一个性能较好的web服务器jvm参数配置: -server//服务器模式-Xmx2g //JVM最大允许分配的堆内存,按需分配-Xms2g //JVM初始分配的堆内存,一般和Xmx配置成一样以避免每次 ...
- JVM CPU Profiler技术原理及源码深度解析
研发人员在遇到线上报警或需要优化系统性能时,常常需要分析程序运行行为和性能瓶颈.Profiling技术是一种在应用运行时收集程序相关信息的动态分析手段,常用的JVM Profiler可以从多个方面对程 ...
随机推荐
- TortoiseSVN SendRpt.exe not found解决方案
重启了Explorer.exe即可.这里也补充下简单的重启Explorer.exe的方法:打开任务管理器,找到“Windows资源管理器”,右键--重新启动. 或者,右键--结束任务,然后点击 文件- ...
- sql sever 基础 建表
---恢复内容开始--- SQL Sever 基础以创建银行数据库bankDB为案例 1.创建数据库 1-1 创建文件夹用以存放数据库 1-2 创建建库bankDB 2.创建数据库 2-1.创建用户信 ...
- js中String 转化为 Date
<script> var s=["2008-8-1","2009/9/2","10/3/2010"]; for(var i=0; ...
- MIP缓存加速原理 MIP不仅仅只是CDN
什么是MIP?我想我们现在都知道.可是你真的了解MIP吗?MIP加速原理是什么?MIP 是用 CDN 做加速的么?准确答案是:是,但不只是. 很多人并认为MIP百度排名会靠前,甚至权重会提高?作为一个 ...
- PHP Laravel 5.4 环境搭建
1.php运行环境搭建 在win10系统上进行搭建的,使用的是wamp环境 wampserver3_x86_apache2.4.17_mysql5.7.9_php5.6.15.exe,安装包中集成了 ...
- TP5部署服务器问题总结
及最近部署TP5遇到了很多坑,各种环境下都会出现一些问题,下面是我记录的排坑之路 先说最简单的lnmp一键安装包,我用的是1.5稳定版 安装命令:wget http://soft.vpser.net/ ...
- Flask初见
Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSIG工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 .Flask使用 BSD 授权. Flask也被称为 “m ...
- 转译符,re模块,random模块
一, 转译符 1.python 中的转译符 正则表达式中的内容在Python中就是字符串 ' \n ' : \ 转移符赋予了这个n一个特殊意义,表示一个换行符 ' \ \ n' : \ \ 表示取 ...
- 【SAPUI5】ODataを構成するもの
はじめに SAPUI5でアプリケーションを作るにあたり.ODataは避けては通れないトピックです.結構広いテーマなので.5-7回くらいに分けて書きたいと思います.1回目はODataの概要について説明し ...
- JSON初体验(一):JsonObject解析
在学校的呆了一段时间,马上又要回去工作了,不说了,我现在介绍一下json相关的内容 1.JSON数据格式(总的来说,json就是一个字符串) 1.整体结构 String json1 = "{ ...