这可能是新手最容易入门的JVM讲解(不过是一场恋爱)
作者:请叫我红领巾,转载请注明出处http://www.cnblogs.com/xxzhuang/p/7453746.html
一.写在前面
首先,本篇文章并没有涉及原理,而是在笔者撸了《深入理解Java虚拟机》好几遍的基础上讲解自己的经验,从一个新手到现在明白JVM是个什么玩意,怎么去理解和明白,讲解这样一个经验而已。这篇文章并对JVM并没有挖掘得很深,在下目前也没有这个能力(笔者目前只是一个正在找工作的大四狗罢了),只是尽量以通熟易懂的方式,让读者理解JVM是个什么玩意。下面开始我的讲解。
二.谁说人神不得相爱——Java的跨平台
理解Java的跨平台特性,是对JVM最直观的认识。所谓的“一次编译,到处运行”,为什么C/C++ 却不能实现呢?这一类语言直接使用物理硬件(或者说操作系统的内存模型),那么不同系统之间的内存模型是不同的,比如说Linux和Window,这就意味,在Window编译好的代码,却不能在Linux上运行。《深入理解Java虚拟机》记录说,Java虚拟机规范中试图定义一种Java内存模型(JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台上都能达到一致性的并发效果。举个现实的例子,一个只会听说中文的人,要如何和一个只会听说英文的人交流,在Java的世界里,采用的方式即是给两边的人各配一名翻译官(JVM),所以,这就是为什么JVM要有window版本,也要有Linux版本。
众所周知,Java的程序编译的最终样子是.class文件,不同虚拟机的对每一个.class文件的翻译结果都是一致的。而对于C/C++而言,编译生成的是纯二进制的机器指令,是直接面对计算机系统的内存,但是,java程序的编译结果是面向JVM,是要交付给JVM,让他再做进一步处理从而让计算机识别运行,这就是所谓的“屏蔽掉各种硬件和操作系统的内存访问差异”。这里的特点又和面向对象推崇的面向接口有着不可描述的关系,我只需要有这么个规范,不需要去知道接触你的底层原理实现。
三.活在梦里的真实——虚拟机
JVM,全称Java Virtual Machine,英文为Java虚拟机,简单的探讨一下虚拟机这三个字,对后面的学习也是挺舒服的。百度百科描述说,“虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统”,但是虚拟机本质还是该计算机系统的一个进程,可以类比香港澳门具有高度自治,但本质上他们还是属于中国的。为了方便描述,我们把整个计算机当成一幢大楼,而虚拟机则是某一个楼层。大楼划分了一个区域给一个楼层,让这个楼层自己管理自己,也就对应着,计算机划分了一个内存给JVM,让JVM自己管理自己。下面这张图是笔者的阿里云服务器上的内存使用情况,可以看到JVM足足占用了接近500M的内存。那么问题来了,JVM要这么多的内存干什么,这里面又是怎么划分?
四.你来到我的世界里——内存
在现阶段无论什么编程语言,都是由人类设计发明的,编程语言对于人类来讲,是方便自己实现目的的工具之一,所以,编程语言看似是全新的东西,但是这里面处处都可以看见人类思想的影子,都可以从现实中找到相似的例子。
接着上面的例子,JVM是作为某一个楼层,单独占有了一大块区域(内存)。这个楼层中,有主厅,客厅,客房,这四个之间的区别之一就行,主厅和客厅是公有的,而主房和客房是私有的,这里对应到JVM层次上即是,有某几块内存,是无论是谁访问,有多少人(线程)访问,这些共有区域都可以为他们服务,而客房,私有区域,假定我们这个楼层比较牛逼,来了多少个客人,就会单独为他们建造每一件客房,每个客人都有自己私有区域,A客人是进不了B客人的房间。
对应的JVM的层次,即是JVM运行时数据区域划分为两大块,线程隔离的区域和线程共享的区域。我们可以简单的理解为,每个客人即是一条线程。具体对应的区域又是如何划分的,又有什么作用,这里只能从概念上理解和记忆了,传送门在此轻松认识JVM运行时数据区域
五.离开我,却没有带走你的痕迹——什么是垃圾
回想起小时候,很多小伙伴都会一起结伴过来我家玩耍,虽然大家玩得很开心,等到了时间点之后,他们就拍拍屁股走人,留下我家里一片狼藉,这个时候如果我不收拾一下垃圾的话,我老妈估计就要来拍拍我的屁股了。客人(线程)同样如此,我来过你的世界,总会留下属于我的痕迹,是不是垃圾,就要看你自己如何判定了。这里就引出另一个问题,我怎么判断是哪个才是垃圾,哪个不是垃圾,只不过是玩耍的时候,我或者小伙伴随手把老妈的戒指扔到地上而已。站在人类的视角上看,一眼就知道哪个是垃圾,哪个不是垃圾,但是计算机可不是这样,计算机有些时候确实不如人类,明明人类一眼或者几秒能完成的事情,要让计算机同样能够完成对应的功能的话,需要付出千万倍的代价才能够实现。
笔者的老妈在家里收拾垃圾的时候,为了确保扔掉的东西是垃圾,她会将这个东西,一个一个问家里的每个人,这个东西是不是你的,你还要不要,当没有一个人承认说这个东西是属于他的时候,老妈就将这个东西视为垃圾,当有人说这个不是垃圾,是他的宝贝的时候,我老妈就这个东西标记一下。JVM采用的是类似的做法,每个对象到GC ROOT都有一定的联系和路径可达,当某个对象,对于GC ROOT不可达(即没有人说这个东西是属于他的)的对象,JVM则判定为垃圾。JVM里称此行为是可达性分析。
finalize的作用:假设一个本子已经被老妈认定为垃圾了,但老妈在扔掉垃圾的时候必须先经过一个程序,即finalize,假如在这个程序过程中,我突然想起这个本子对我还是有用的,那么这个本子就不会被认定为垃圾,从而继续保留在内存中。
六. 我要怎样忘了你是谁——垃圾回收算法
知道什么是垃圾,找到了垃圾的位置,接下来的问题是我要怎么处理这个垃圾,即垃圾回收。我要怎样忘了你是谁,关键是要怎么字,这个动作是怎么发生的。
标记清除:在这个楼层中,垃圾四处都有,甚至散乱在非垃圾之间或者周围,即然我老妈已经给有用的东西做个标志,那么这就意味着我老妈只需要清除那些没有标识的东西。标记清除的做法形象成就是我老妈拿着垃圾桶,从头到尾,看到垃圾就把他扔到垃圾桶里面。这种做法无疑是最简单的,但是带来的后果也是很明显的,空间碎片太多。这里的空间碎片又要做如何理解,每个物品(每个对象)都是需要占据着一定的的面积(即内存),他要站住脚跟嘛,但是如果空间碎片的太多,就会导致大的物品来临的时候,区域(内存)不够用,就会再次引发垃圾回收(意味着你打游戏的时候可能要停顿个几秒)。再举个现实中的例子,打包行李箱的时候,随随便便,散乱的放置东西,行李厢很容易被撑满,这个时候你还想放一双鞋进去,你会发现空间不够用,只能把所以东西都倒出来,整整齐齐的,从上到下从左到右的放置物品。对于空间的利用率,整齐的做法比散乱无章的行为更来得高,这就引出了另外一个做法,标记整理算法。
标记整理:你见过有谁扫地的时候,看到垃圾就直接把扫到扫帚了里面,看到就扫。不存在的!人是有惰性的,所有总会找到更高效的做法,更习惯的做法是将垃圾扫到一起,再统一将其扔到垃圾桶中。
复制:这个算法就有点奢侈了,不管这个内存里有多少垃圾,我老妈都统一将他们扔掉,然后重新再买一次那些我们还需要用的物品,俗称复制。因此,如果存活对象太多,这个算法是不适合的(想想就知道了-.-),其二,JVM里面需要将可用内存分为两半,一半供目前使用,一半供复制后的对象使用。
未完待续……
这可能是新手最容易入门的JVM讲解(不过是一场恋爱)的更多相关文章
- .NetCore微服务Surging新手傻瓜式 入门教程 学习日志---先让程序跑起来(一)
原文:.NetCore微服务Surging新手傻瓜式 入门教程 学习日志---先让程序跑起来(一) 写下此文章只为了记录Surging微服务学习过程,并且分享给广大想学习surging的基友,方便广大 ...
- .NetCore微服务Surging新手傻瓜式 入门教程 学习日志---结构简介(二)
原文:.NetCore微服务Surging新手傻瓜式 入门教程 学习日志---结构简介(二) 先上项目解决方案图: 以上可以看出项目结构可以划分为4大块,1是surging的核心底层,2,3,4都可以 ...
- [转]Scrapy简单入门及实例讲解
Scrapy简单入门及实例讲解 中文文档: http://scrapy-chs.readthedocs.io/zh_CN/0.24/ Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用 ...
- 新手如何快速入门Python
学习任何一门语言都是从入门(1年左右),通过不间断练习达到熟练水准(3到5年),少数人最终能精通语言,成为执牛耳者,他们是金字塔的最顶层.虽然万事开头难,但好的开始是成功的一半,今天这篇文章就来谈谈如 ...
- 新手如何快速入门node.js
附Java/C/C++/机器学习/算法与数据结构/前端/安卓/Python/程序员必读书籍书单大全: 书单导航页(点击右侧 极客侠栈 即可打开个人博客):极客侠栈 ①[Java]学习之路吐血整理技术书 ...
- mysql 命令行操作入门(详细讲解版)
之前分享过多次Mysql主题,今天继续分享mysql命令行入门 1. 那么多mysql客户端工具,为何要分享命令行操作? -快捷.简单.方便 -在没有客户端的情况下怎么办 -如果是mysql未开启 ...
- Spring Boot 入门教程 | 图文讲解
目录 一.Spring Boot 是什么 二.为什么要使用 Spring Boot 三.快速入门 3.1 创建 Spring Boot 项目 3.2 项目结构 3.3 引入 Web 依赖 3.4 编写 ...
- Scrapy简单入门及实例讲解
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以 ...
- Scrapy简单入门及实例讲解-转载
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以 ...
随机推荐
- Python基础之内置函数和递归
一.内置函数 下面简单介绍几个: 1.abs() 求绝对值 2.all() 如果 iterable 的所有元素都为真(或者如果可迭代为空),则返回 True 3.any() 如果 iterable 的 ...
- JDK+Tomcat+Zookeeper+DubboAdmin安装教程
JDK+Tomcat+Zookeeper+DubboAdmin安装教程 1. 安装内容: JDK 1.8.131 Tomcat 7.0.77 Zookeeper 3.4.9 Dubbo admin 2 ...
- maven - 引用本地jar,进行jar包移动
背景: 项目为maven工程,部分jar需要需用项目单独修改的本地jar包. 配置好scope后发现构建后引用的jar没有移动到对应的目录,百度后发现需要配置以下依赖 <plugin> & ...
- (转)Linux(Centos)之安装Java JDK及注意事项
场景:天下事有难易乎?为之,则难者亦易矣:不为,则易者亦难矣.人之为学有难易乎?学之,则难者亦易矣:不学,则易者亦难矣. 1 准备工作 下面配置jdk的方式在具有root权限时候能够执行.如果没有ro ...
- (转)简单介绍java Enumeration
简单介绍java Enumeration 分类: java技术备份 java数据结构objectstringclass存储 Enumeration接口 Enumeration接口本身不是一个数据结构 ...
- node.js fs.open 和 fs.write 读取文件和改写文件
Node.js的文件系统的Api //公共引用 var fs = require('fs'), path = require('path'); 1.读取文件readFile函数 //readFile( ...
- 基于FPGA的VGA显示静态图片
终于熬到暑假了,记过三四周的突击带考试,终于为我的大二画上了一个完整的句号,接下来终于可以静心去做自己想做的事情了,前一阵子报了一个线上培训班,学学Sobel边缘检测,之前一直在学习图像处理,但是因为 ...
- python3网络编程之socket
文章内容: socket介绍 socket参数介绍 流程描述 socket对象内建方法 基本socket实例 通过socket实现简单ssh并实现接收大数据 socket介绍 socket又称&quo ...
- 花了一年时间开发的三维弯管机交互式转档软件(三维管子模型UG,SOLIDWORK,PRO/E文件转成YBC)
在弯管机加工中,由管子模型生成可直接进行弯管加工的YBC数据可以大大提高弯管编程过程.传统的做法是先用dxf数据文件(用autocad绘制管子的轴心线数据)转出XYZ数据,然后由XYZ数据转成YBC数 ...
- Redis-主从配置了解
集群的作用: 主从备份, 防止主机宕机(相当于从服务器为主服务器担任备份的作用) 读写分离, 分担master的任务 任务分离, 如从服务器分别分担备份工作和计算工作 redis集群方式 星形: 众多 ...