前言

  谈到JAVA,就不得不提JVM---JAVA程序员绕不开的话题.也许有童鞋会说,我不懂JVM,但是我一样可以写出JAVA代码,我相信说这种话的童鞋,往往是只有1-3年的初级开发人员,对JAVA理解还不深,不明白JVM的重要性,那接下来我们来说说,为什么要学习JVM?
  1.理解JVM,才能帮助我们写出更好,更健壮的代码.举个例子,以下代码的执行结果会是什么呢?很多童鞋肯定会说:嗯?当我傻吗?两个不都是true吗?这有啥好说的,真的是这样吗?感兴趣的童鞋可以自己下来试一试,至于为什么是这样的结果,在下文会解释清楚.

  2.理解JVM,可以帮助我们提升JAVA程序的性能,排除问题.
  3.也是最重要的一点,面试必问!

虚拟机的种类

  我们知道,目前使用范围最广的虚拟机是sun公司的HotSpot VM,在这之前,sun公司发布的第一款虚拟机是Sun Classic/Exact VM,这是世界上第一款商用虚拟机.另外其他公司也有自己的虚拟机,比如IBM J9 VM,Google Android Dalvik VM,Apache Harmony,Microsoft VM等待,但是使用范围最广的还是HotSpot.

JVM内存划分

  引用一张图来说明:

  可以看到,JVM主要由方法区/堆区/虚拟机栈/本地方法栈/程序计数器五个部分组成,从线程的角度来看,分为线程公有的部分(方发区/java堆)和线程私有的部分(虚拟机栈/本地方法栈/程序计数器).

方法区

  存放已经被虚拟机加载的[类信息/常量/静态变量/即时编译后的代码]等,有些文章也称方法区为永久代,主要发生的异常是内存溢出:OutOfMemoryError.另外在JDK1.6版本中,常量池(这里特指运行时常量池,我们一般说的常量池也都是指的运行时常量池)是存放于方法区中的(因此方法区可能会经常内存溢出),JDK1.7的时候常量池移到了JAVA堆(Heap)中,在JDK1.8的时候,已经没有方法区了,取而代之的是一块叫元数据(metaSpace)的空间.

java堆

  java堆主要存放的是对象实例以及数组等信息,主要发生的异常仍然是内存溢出:OutOfMemoryError.并且java堆区是GC重点关注的区域.另外,我们常说,几乎所有的对象分配内存都是在java堆中进行,而不是说所有对象100%都在java堆中分配内存,是因为有两种例外情况不会在java堆中分配内存,第一种是TLAB(线程本机分配缓存),另一种是栈上分配,既然想成为一名架构师,童鞋们应该要弄明白什么是TLAB和栈上分配,发挥你们的能力,尽情Google吧.

虚拟机栈

  java方法执行的内存模型,每个方法在执行的时候会封装成一个栈帧,存放[局部变量表/操作数栈/本动态链表/方法出口]等信息,方法的执行对应栈帧入栈和出栈的过程.栈的深度是有大小的,默认情况下栈的内存为1M,因此虚拟机栈除了发生内存溢出异常,还有可能发生StackOverFlowError异常.

本机方法栈

  和虚拟机栈作用类似,区别在于本地方法栈保存的是native方法的信息.

程序计数器

  当前线程执行的字节码行号指示器,是JVM中唯一一块没有内存溢出异常的区域.

常量池

  接下来我们再倒回来看看,文章开头的代码,执行结果会是什么:

  127返回的是true,128返回的确是false.为什么?
  首先我们知道,在java语言中 == 比较的是两个对象的内存地址,只有equals方法才是比较两个对象是否相等,执行结果告诉我们,值都为127的Integer a和b内存地址是相同的,他们是同一个对象,而值为128的Integer c和d的内存地址不同,他们是不同的两个对象,那为什么127就是相同的对象,128就是不同的对象呢?还记得上文中,我们说方法区中有一块区域叫运行时常量池,存放的是各种常量,java语言对byte/short/char/int/string设置了常量池,比如我们查看Integer的源码:

  可以发现,Integer的常量池范围是-128~127,在该范围内的Integer对象都会复用常量池中的值,因此a和b是相同对象,而超过该范围,会重新new一个新的对象,因此c和d都是重新new出来的,地址当然不同,因此是false.另外String类型的常量池和前面四种类型不一样,String类型的常量池是通过final来实现的.而float/double没有常量池的概念,因为float和double本身都是科学技术法表示近似数,无法精确计算,存在精度丢失的情况,因此没法为float和double创建常量池.

  本文我们了解了JVM的内存区域,下一篇文章,让我们来学习类加载机制,敬请期待!

  如果觉得博主写的不错,欢迎关注博主微信公众号,博主会不定期分享技术干货!
  

本文由博客一文多发平台 OpenWrite 发布!

【JAVA进阶架构师指南】之二:JVM篇的更多相关文章

  1. 【JAVA进阶架构师指南】之四:垃圾回收GC

    前言   在[JAVA进阶架构师指南]系列二和三中,我们了解了JVM的内存模型以及类加载机制,其中在内存模型中,我们说到,从线程角度来说,JVM分为线程私有的区域(虚拟机栈/本地方法栈/程序计数器)和 ...

  2. 【JAVA进阶架构师指南】之五:JVM性能调优

    前言   首先给大家说声对不起,最近属实太忙了,白天上班,晚上加班,回家还要收拾家里,基本每天做完所有事儿都是凌晨一两点了,没有精力再搞其他的了.   好了,进入正题,让我们来聊聊JVM篇最后一个章节 ...

  3. 【JAVA进阶架构师指南】之一:如何进行架构设计

    前言   本博客是长篇系列博客,旨在帮助想提升自己,突破技术瓶颈,但又苦于不知道如何进行系统学习从而提升自己的童鞋.笔者假设读者具有3-5年开发经验,java基础扎实,想突破自己的技术瓶颈,成为一位优 ...

  4. 【JAVA进阶架构师指南】之三:深入了解类加载机制

    前言   在上一篇文章中,我们知道了JVM的内存划分,其中在说到方法区的时候说到方法区中存放的信息包括[已被JVM加载的类信息,常量,静态变量,即时编译的代码等],整个方法区其实就和类加载有关. 类加 ...

  5. java架构师视频教程 内含activemq+jvm+netty+dubbo

    目录: 架构师视频教程包含activemq jvm netty dubbo 0分布式项目实战所有视频(分布式项目视频)互联网架构师第二期-视频部分互联网架构师第二期-资料部分1.Netty快速入门教程 ...

  6. Java互联网架构师系统进阶课程学习 (4)【享学】

    Java互联网架构师系统进阶课程学习 (4)[享学] 4.显式锁和AQS   显式锁 Lock接口和核心方法 Lock接口和synchronized的比较 synchronized 代码简洁,Lock ...

  7. 15套java互联网架构师、高并发、集群、负载均衡、高可用、数据库设计、缓存、性能优化、大型分布式 项目实战视频教程

    * { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩 展 ...

  8. 图灵学院JAVA互联网架构师专题学习笔记

    图灵学院JAVA互联网架构师专题学习笔记 下载链接:链接: https://pan.baidu.com/s/1xbxDzmnQudnYtMt5Ce1ONQ 密码: fbdj如果失效联系v:itit11 ...

  9. JAVA兼职架构师

    在一些小企业或者公司人力不足的时候,经常会出现一个人干多个人的活.开发可能会干架构.测试.运维,一些小项目可能需要一个人完成.我把这些角色合并在一起称之为兼职架构师. 我用我的经历来说说兼职架构师的需 ...

随机推荐

  1. 【React.js小书】动手实现 React-redux(五):Provider - 方志

    我们要把 context 相关的代码从所有业务组件中清除出去,现在的代码里面还有一个地方是被污染的.那就是 src/index.js 里面的 Index: 1234567891011121314151 ...

  2. 吴裕雄--天生自然KITTEN编程:逃脱升天

  3. js javascript 获取url,获得当前页面的url,静态html文件js读取url参数

    获得当前页面的url window.location.href 静态html文件js读取url参数 location.search; //获取url中"?"符后的字串 下边为转载的 ...

  4. 奇葩念头:微信能取代WP应用吗

         墙倒众人推,原本是再平常不过的事,但每次发生都显得特别凄凉--就和楼市买房买涨不买跌一样,在互联网行业,用户数量越多的产品或服务,就会越受到行业和大众青睐.而越是小众的产品或服务,虽然是要走 ...

  5. 携程酒店DevOps测试实践

    作者简介 王幸福,携程酒店研发部高级测试经理,负责无线自动化测试相关工作.在测试框架和平台研发.移动测试.DevOps等领域有着丰富的经验. 如今很多大型互联网公司.创新型企业都在积极地进行DevOp ...

  6. 在python使用selenium获取动态网页信息并用BeautifulSoup进行解析--动态网页爬虫

    爬虫抓取数据时有些数据是动态数据,例如是用js动态加载的,使用普通的urllib2 抓取数据是找不到相关数据的,这是爬虫初学者在使用的过程中,最容易发生的情况,明明在浏览器里有相应的信息,但是在pyt ...

  7. tar:file-changed-as-we-read-it报错处理

    在使用tar命令对Mysql的数据目录进行备份打包时出现如下报错: tar cvzf mysql.tgz mysql /bin/tar: /path/to/mysql: file changed as ...

  8. Git学习笔记(二) · 非典型性程序猿

    远程库的使用 前面说到的都是git在本地的操作,那么实际协作开发过程中我们肯定是要有一个远程版本库作为项目的核心版本库,也就是投入生产使用的版本.这里我们以 Github为例.Github是一个开放的 ...

  9. 纯css3配合vue实现微信语音播放效果

    前言 每次写点东西都扯两句-0-,这几天一半精力放在移动端,一半维护之前的项目.书也少看了,不过还好依旧保持一颗学习的心.对于css3我是之前有专门整理过的,因此对于原理之前也算了解.今天是项目中遇到 ...

  10. Leetcode 20题 有效的括号(Valid Parentheses) Java语言求解

    题目描述: 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合. 左括号必须以正确的顺序闭合. 注意空 ...