为什么要写这么一篇文章呢,因为很基础,很基础,很基础,重要的事情说三遍!!!哼,还不是因为面试的时候经常会被问到,哈哈哈哈哈 ,为此我静下心来,狠心写下了这一篇文章,好去对付一般的面试官,也可以帮助你更好的去理解,这是一场恶战,让我们磨好枪准备开干吧。

先让我们看一看这张图,相信大家也看过很多次了,这一次让我们不醉不归 ,干杯!

(红框为线程共享的数据区、篮框为线程隔离的数据区)

Java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域各有各的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。

看上图我们就清楚运行时数据区分为以下几个部分:

一、 让我们干一杯吧!第一杯敬 程序计数器

程序计数器时一块儿较小的内存空间,它可以看作时当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。它是线程私有的,每个线程都需要一个独立的程序计数器。

如果线程执行的是一个Java方法,计数器记录的是正在执行的虚拟机字节码指令的地址;

如果正在执行的是一个Native方法,计数器值为空(Undefined)。

此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError异常的区域

二、 再喝完这杯还有三杯!!!【Java虚拟机栈】

线程私有,生命周期与线程相同。

虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程

在Java虚拟机规范中,对这个区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;

如果虚拟机栈可以动态扩展,扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常;

三、 第三杯【本地方法栈】

本地方法栈与虚拟机栈的作用时相似的,它们之间的区别是:虚拟机栈为虚拟机执行Java方法(也就是字节码)服务;本地方法栈则为虚拟机使用到的Native方法服务;本地方法栈也会抛出StackOverflowError异常和OutOfMemoryError异常。

四、 喝完这一杯,真的只有最后一杯【Java堆】

所有线程共享的一块内存区域,在虚拟机启动时创建。此内存对象的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

Java堆是垃圾收集器管理的主要区域,因此也可以称之为“GC”堆(Garbage Collected Heap),或者是“垃圾堆”,这句话是开玩笑的。现在的垃圾收集器都采用的是分代收集算法,所以Java堆细分为了:新生代和老年代(这部分放在后面在详解);无论如何划分区域,都与存放内容无关,无论哪个区域,存储的都是对象实例,是为了更好的回收内存,或者说是更快的分配内存。

Java虚拟机规范的规定,Java堆可以处于物理上不连续的内存空间,只要逻辑上是连续的即可。在实现时,既可以实现成固定大小的,也可以实现成可扩展的,当前主流的虚拟机都是按照可扩展的来实现的(通过-XmxXms控制)。如果在堆中没有足够内存完成实例分配,并且堆也无法再扩展时,将会抛OutOfMemoryError异常。

光说没用,直接上才艺!

代码演示堆内存的使用大小,运行原理(在Run as ->Run Configurations中输入"-XX:+PrintGCDetails"可以查看堆内存运行原理图)

public class JVMTest {public static void main(String[] args) {long maxMemory = Runtime.getRuntime().maxMemory(); //Java虚拟机试图使用的最大内存long totalMemory = Runtime.getRuntime().totalMemory(); //Java虚拟机中的内存总量System.out.println("MAX_MEMORY = " + maxMemory + "(字节)" + (maxMemory / 1024 / 1024) + "MB");System.out.println("TOTOL_MEMORY = " + totalMemory + "(字节)" + (totalMemory / 1024 / 1024) + "MB");}}

运行后的结果如下图所示:

当然也可以通过设置参数触发垃圾回收(在Run as ->Run Configurations中输入设置“-XX:+PrintGCDetails”可以参看垃圾回收机制原理)

public class JVMTest {public static void main(String[] args) {long maxMemory = Runtime.getRuntime().maxMemory(); //Java虚拟机试图使用的最大内存long totalMemory = Runtime.getRuntime().totalMemory(); //Java虚拟机中的内存总量System.out.println("MAX_MEMORY = " + maxMemory + "(字节)" + (maxMemory / 1024 / 1024) + "MB");System.out.println("TOTOL_MEMORY = " + totalMemory + "(字节)" + (totalMemory / 1024 / 1024) + "MB");String str = "hello world, JVM!";while (true) {str += str + new Random().nextInt(88888888) + new Random().nextInt(99999999);}}}

运行如下图所示:

五、 最后一杯,干了我们是好朋友【方法区】

线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

方法区也不要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集。大多在HotSpot虚拟机上开发的程序员也会把方法区称之为“永久代”,是因为垃圾收集扩展至了方法区,但并不是说数据进入了方法区(永久代)中,就如“永久代”的名字 一样永久存在了,只是相对来说垃圾收集在这个区域时比较少出现的。这区域的内存回收目标主要是针对常量池的回收和堆类型的卸载,一般来说,这个区域的回收结果比较难以令人满意,可能会导致内存泄漏,但是这个区域的回收还是必要的。

当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

运行时常量

池属于方法区中的一部分。class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项是常量池,用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后进入方法去的运行时常量池中存放。

运行时常量池相对于class文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只能在编译器才能产生,运行期间也可以将新的常量放入池中,这种特性被开发人员利用的比较多的是String类的intern()方法。

运行时常量池时方法区的一部分,自然会受到方法区的限制,当常量池无法再申请到内存时会抛出OutOfMemoryError异常。

干了这五杯酒之后,上图就变成了以下这个样子

至此,我们5杯酒就喝完了,想必很多同学已经上头了吧,微醺刚刚好,拿去干面试官去!如果同学们还有点儿晕,不要紧,让我们以后继续喝,必须把你的量给练上去,以后碰到哪个面试官都不怕。


原作者: L先生
原文链接:酒后系列:被某厂面试官吊打后酒后整理的JVM干货
原出处:公众号

java runtime ssh 后执行指令_酒后系列:被某厂面试官吊打后酒后整理的JVM干货相关推荐

  1. 过于自信,面试普通Java岗被面试官吊打了。。。

    是的,诸位没有看错,这篇文章的要讲述的并不是我吊打面试官,而是一段我被面试官吊打的陈年往事,这段痛苦的记忆在我脑海中长久不衰,也是一个我内心曾多次不愿面对的事实,各位看官可以准备好一小把瓜子,听我将这 ...

  2. 惨遭面试官吊打高并发系统设计,回来学习 2400 小时后成功复仇

    惨遭面试官吊打高并发系统设计,回来学习 2400 小时后成功复仇原创 2021-06-22 06:35·Java 小菜去年的金九银十,我和大多数的同行一样加入了升职涨薪的潮水,我早在 2 个月前就开始 ...

  3. Java面试题总结(乱序版,来自大厂面试官的MySQL灵魂十连问

    Synchronized是java语言的关键字,是原生语法层面的互斥,需要JVM实现:ReentrantLock 是JDK1.5之后提供的API层面的互斥锁,需要lock和unlock()方法配合tr ...

  4. 【拥抱大厂系列】几个面试官常问的垃圾回收器,下次面试就拿这篇文章怼回去!

    点个赞,看一看,好习惯!本文 GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了3个月总结的一线大厂Java面试总结,本人已拿腾 ...

  5. jdk开发文档_【第9期】面试官:JDK、JRE、JVM 三者什么关系?

    这个题目在面试题中基本没怎么出现,但在笔试题中倒是经常见到.所以还是有必要拉出来溜溜~ JDK: java development kit, java开发工具包,用来开发Java程序的,针对java开 ...

  6. .net 怎么在控制器action中返回一个试图_一个view事件分发,面试官6连问直击灵魂,我被虐的体无完肤...

    注:原文来自掘金作者xiangcman 写这篇文章其实是有原因的,说实话这次面试真的很失败,看着身边的人都拿到了高薪的工资,感觉自己还是有些惭愧.也更说明自己在很多方面的知识点还是不够扎实,于是再一次 ...

  7. 三年Java后端裸辞跳槽面试,却被面试官吊打

    目前已经是疫情后面试跳槽阶段,相信有不少程序员蠢蠢欲动,开始出去试试水,想要跳槽涨薪了!有一个朋友就想改变现状,于是找了大量网上的面试题,强行记下之后,开始出去"试水". 他试水之 ...

  8. 三年Java后端裸辞跳槽面试,却被面试官吊打...

    前段时间不是程序员面试热潮嘛,所以辞职的,跳槽的特别多,都是累积了两三年工作经验,想出去试试水看能不能拿到更高的薪资.这不,我有个朋友就想改变现状,啥也没准备,直接裸辞去找公司面试了. 试水之后回来和 ...

  9. 惨遭腾讯面试官吊打高并发系统设计,回来学习2400小时后成功复仇!

    去年的金九银十,我和大多数的同行一样加入了升职涨薪的潮水,我早在2个月前就开始准备,我觉得自己在技术方面完全没有问题,于是这两个月我每天在公司摸鱼2小时,回家刷2小时,前前后后刷了几千到面试题,Lee ...

最新文章

  1. 谈谈对 Spring 的理解
  2. A quick presentation of the Visual Studio 2010 editions per role
  3. mysql 8.0数据备份恢复_RDS for MySQL8.0物理备份恢复到本地自建数据库
  4. java建立类的思想_JAVA类和对象创建
  5. AjaxControlToolKit插件tabContainer在IIS7以上版本部署后自动添加visibility:hidden属性 问题的解决方案...
  6. Qt学习笔记之GUI基本知识
  7. php 保存json格式数组 json_encode /u 不转义
  8. 【Android】科大讯飞——语音识别
  9. android 远程连接电脑屏幕,Android安卓手机3389远程连接电脑桌面教程
  10. java 集合底层_java集合底层实现总结
  11. UESTC 1636 梦后楼台高锁,酒醒帘幕低垂 最小生成树Kruskal算法的扩展
  12. springboot点餐微信小程序毕业设计源码221144
  13. 《点燃我,温暖你》爱心代码复现
  14. Chrome浏览器搜索引擎问题
  15. 苹果考虑推迟发布5G iPhone
  16. 病毒丨熊猫烧香病毒分析
  17. unicode 生僻字_[微软拼音小技巧] 如何用Unicode输入生僻字
  18. python怎么模拟鼠标移动点击_Python模拟鼠标点击——如何正确的肝阴阳师
  19. 2022-2028年中国特种食用油行业市场运营格局及前景战略分析报告
  20. 计算机网络知识点总结(计网期末盲押系列)

热门文章

  1. MYSQL-创建事件
  2. 是谁扼杀了员工的敬业度?[转]
  3. “王炸”来了?苹果下一代Mac Pro将搭载两颗M1 Ultra芯片
  4. 李佳琦“云逛”进博会 携手央视带货阿富汗松子
  5. 格力接受美国5.83亿巨额罚款!官方紧急回应...
  6. 国家网信办:掌握超过100万用户个人信息运营者赴国外上市需申报审查
  7. 这届年轻人,连泡面也买不起了
  8. 市场观察人士:有充足代工产能支持 联发科3月份营收有望创下新高
  9. 快手上市首日涨近161% 两大创始人身家破千亿
  10. iPhone 12还没出,iPhone 13开始了:将采用120Hz ProMotion显示屏