Java岗位面试,JVM是对程序员基本功考察,通常会问你对JVM了解吗?

可以分几部分回答这个问题,首先JVM内存划分 | JVM垃圾回收的含义  |  有哪些GC算法  以及年轻代和老年代各自特点等等。

1) JVM内存划分:


①  方法区 (线程共享)  常量  静态变量  JIT(即时编译器)编译后代码也在方法区存放

②  堆内存 (线程共享) 垃圾回收的主要场地

③  程序计数器  当前线程执行的字节码的位置指示器

④  Java虚拟机栈(栈内存) :保存局部变量,基本数据类型以及堆内存中对象的引用变量

⑤ 本地方法栈  (C栈):为JVM提供使用native方法的服务

通过这幅图了解一下

JDK 1.8同JDK 1.7 最大的区别是:元数据区取代了永久代.元数据区的本质和永久代类似,都是对JVM规范中的方法区的实现.元数据区和永久代之间的最大区别在于:元数据区不在虚拟机中,而是在本地内存中

详细了解一下各个部分

01)程序计数器(PC寄存器)

程序计数器的定义: 程序计数器是一块较小的内存空间,是当前线程正在执行的那一条字节码指令的地址,若当前线程正在执行的是一个本地方法,那么此时程序计数器为Undefined

程序计数器的作用:

  • 字节码解释器通过改变程序计数器来依次获取指令,从而实现代码的流程控制

  • 在多线程情况下,程序计数器记录的是当前线程执行的位置,从而当线程切换回来时,就知道上次线程执行到哪了

程序计数器的特点

  • 是一块较小的内存空间

  • 线程私有,每个线程都有自己的程序计数器

  • 生命周期:随着线程的创建而创建,随着线程的销毁而销毁

  • 是一个唯一不会出现OutOfMemoryError的内存区域

02)Java虚拟机栈

定义: 描述Java方法运行过程的内存模型

Java虚拟机栈会为每一个即将运行的Java方法创建一块叫做"栈帧"的区域,用于存放该方法运行过程中的一些信息,如 : 局部变量表  /操作数栈 /动态链接 /方法出口信息  .............

压栈出栈过程:

当方法运行过程中需要创建局部变量时,就将局部变量的值存入栈帧的局部变量表中

Java虚拟机栈的栈顶是当前正在执行的活动栈,也就是当前正在执行的方法,PC寄存器也会指向这个地址,只有这个活动的栈帧的本地变量可以被操作数栈操作,当前这个栈帧中调用另一个方法,与之对应的栈帧又会被创建,新创建的栈帧压入栈顶,变成当前的活动栈帧,方法结束后,当前栈帧的返回值变成新的活动栈帧中的操作数栈的一个操作数,如果没有返回值,那么新的活动栈帧中操作数栈的操作数没有变化

由于Java虚拟机栈是线程对应的,数据不是共享的,因此不用关心数据一致性问题,也不会存在同步锁的问题

特点

  • 局部变量表随着栈帧的创建而创建,它的大小在编译时确定,创建时只需分配事先规定的大小即可,在方法运行的过程中,局部变量表的大小不会发生变化

  • Java虚拟机栈会出现两种异常:StackOverFlowError和OutOfMemoryError

  • StackOverFlowError:若Java虚拟机栈的大小不允许动态扩展,那么当前线程请求的栈的深度超过当前的Java虚拟机栈的最大深度时,就会抛出此异常

  • OutOfMemoryError:若允许动态扩展,那么当前线程的请求的栈内存用完了,无法再动态扩展时,抛出此异常

  • Java虚拟机栈也是线程私有,随着线程创建而创建,随着线程的结束而销毁

03)本地方法栈(C栈)

定义: 是为了JVM运行native方法准备的空间,由于很多native方法都是用C语言实现的,所以通常又叫C栈,它与Java虚拟机栈实现的功能类似,只不过本地方法栈是描述本地方法运行过程的内存模型

栈帧变化过程:

本地方法被执行时,在本地方法栈也会创建一块栈帧,用于存放该方法的局部变量表 /操作数栈 /动态链接 /方法出口 等信息; 方法结束后,相应的栈帧也会出栈,并释放内存空间.也会抛出StackOverFlowError和OutOfMemoryError异常

04) 堆

定义: 堆是用来存放对象的内存空间,几乎所有的对象都存储在堆中

特点:

  • 线程共享,整个Java虚拟机只有一个堆,所有线程都访问同一个堆.

  • 在虚拟机启动时创建

  • 是垃圾回收的主要场地

  • 进一步可分为:新生代(Eden区 From Survior To Surviror)  老年代

  • 不同的区域存放了不同生命周期的对象,这样可以根据不同区域使用不同的垃圾回收算法,更具有针对性. 堆的大小也可以固定也可以扩展,对于主流的虚拟机,堆大小是可扩展的,因此当线程请求分配的内存,但堆已满,且内存已无法再扩展时,就抛出OutOfMemoryError异常

05)方法区

定义: Java虚拟机规范中定义方法区是堆的一个逻辑部分,方法区存放以下信息: 已被虚拟机加载的类信息 /常量 /静态变量 /即时编译后代码

特点:

  • 线程共享.方法区是堆的一个逻辑部分,因此和堆一样,都是线程共享,整个虚拟机中只有一个方法区

  • 永久代 方法区中的信息一般需要长期存在,而且它又是堆的逻辑分区,因此用堆的划分方法,把方法区称为"永久代"

  • 内存回收的效率低.方法区中的信息一般需要长期存在,回收一遍只有少量信息无效.主要回收的目标是: 对常量池的回收;对类型的卸载

  • Java虚拟机规范l对方法区的要求比较宽松,和堆一样,允许固定大小.也允许动态扩展,还允许不实现垃圾回收

运行时常量池:

方法区中存放:类信息  常量  静态变量  即时编译器编译后的代码.常量就存放在运行时常量池中.当类被Java虚拟机加载后,.class文件中的常量就存在方法区的运行时常量池,而且在运行期间,可以向常量池中添加新的常量,如String类的intern()方法就能在运行期间向常量池中添加字符串常量

06) 直接内存(堆外内存)

直接内存是除Java虚拟机之外的内存,但有可能被Java使用

操作直接内存:

在NIO中引入了一种基于通道和缓存的IO方式,他可以调用本地方法直接分配Java虚拟机之外的内存,然后通过一个存储在堆中的DirectByteBuffer对象直接操作该内存,而无需将外部内存中数据复制到堆中再进行操作,从而提高数据操作的效率,直接内存的大小不受Java虚拟机限制,也会抛出OutOfMemoryError异常

直接内存和堆内存比较:

  • 直接内存申请空间耗费更高的性能

  • 直接内存读取IO的性能优于普通的堆内存

  • 直接内存的作用链:本地IO-->直接内存-->本地IO

  • 堆内存的作用链:本地IO-->直接内存-->非直接内存-->直接内存--->本地IO

  • 服务器管理员在配置虚拟机参数时,会根据实际内存设置 -Xmx等参数信息,但经常忽略直接内存,使得各个内存区域总和大于物理内存,从而导致动态扩展时出现OutOfMemoryError

2)类似 -Xms  -Xmn这些参数的含义


堆内存分配

① : JVM初始分配的内存由-Xms指定,默认是物理内存的1/64

②:  JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4

③: 默认空余堆内存小于40%时,JVM就会增加堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制

④: 因此服务器一般设置-Xms  -Xmx相等以避免在每次GC后调整堆大小. 对象的堆内存由垃圾回收器的自动内存管理系统回收

非堆内存分配:

①:JVM使用-XX:PermSize 设置非堆内存的初始值,默认是物理内存的1/64;

② :由XX:MaxPermSize设置最大非堆内存的大小

③: -Xmn2G :设置年轻代的大小为2G

④ :-XX:SurvivorRatio ,设置年轻代中Eden区与Survivor区的比值

3)垃圾回收的算法有哪些?


① 引用计数法:原理是在此对象有个引用,则增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只收集计数为0的对象.此算法最致命的是无法处理循环引用的问题

②: 标记-清除 :此算法分两个阶段,第一阶段从引用的根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除,此算法需要暂停应用,同时产生内存碎片

③: 复制算法 此算法把内存划分为两个相等的区域,每次只使用一个区域,垃圾回收时,遍历当前使用的区域,把正在使用的对象复制到另一个区域中,算法每次只处理正在使用的对象,因此复制的成本比较小,同时复制过去以后还能进行相应的内存整理,不会出现"碎片问题",此算法的缺点也很明显,需要两倍的内存空间

④: 标记-整理:此算法结合了"标记-清除"和"复制算法"的两个的优点,也是分两个阶段,第一个阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,清除未标记的对象并且把存活的对象"压缩"到堆的其中一块,按顺序排放,,此算法避免"标记-清除"的碎片问题,同时也避免"复制"的空间问题

4)root搜索算法中,哪些可以作为root?


  • 被启动类(bootstrap加载器)加载的类和创建的对象

  • JavaStack中引用的对象(栈内存中引用的对象)

  • 方法区中静态引用

深入浅出 Java 中 JVM 内存管理相关推荐

  1. 形式参数内存在哪java_深入浅出Java中JVM内存管理

    原标题:深入浅出Java中JVM内存管理 Java岗位面试,JVM是对程序员基本功考察,通常会问你对JVM了解吗?可以分几部分回答这个问题,首先JVM内存划分 | JVM垃圾回收的含义 | 有哪些GC ...

  2. java中JVM内存管理(1)

    Java岗位面试,JVM是对程序员基本功考察,通常会问你对JVM了解吗?  可以分几部分回答这个问题,首先JVM内存划分 | JVM垃圾回收的含义  |  有哪些GC算法  以及年轻代和老年代各自特点 ...

  3. java jvm内存模型_Java(JVM)内存模型– Java中的内存管理

    java jvm内存模型 Understanding JVM Memory Model, Java Memory Management are very important if you want t ...

  4. Swift 中的内存管理详解

    这篇文章是在阅读<The Swift Programming Language>Automatic Reference Counting(ARC,自动引用计数)一章时做的一些笔记,同时参考 ...

  5. 详解JVM内存管理与垃圾回收机制5 - Java中的4种引用类型

    在Java语言中,除了基础数据类型的变量以外,其他的都是引用类型,指向各种不同的对象.在前文我们也已经知道,Java中的引用可以是认为对指针的封装,这个指针中存储的值代表的是另外一块内存的起始地址(对 ...

  6. JVM基础 之Java HotSpot虚拟机中的内存管理

    1  简介 依托JavaTM 2平台的力量,标准版(J2SETM)实现了内存的自动管理,将开发人员从复杂的显式内存管理中解放出来. 本文将对Sun公司的J2SE发行版中的Java HotSpot虚拟机 ...

  7. JVM内存管理:深入Java内存区域与OOM

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝 ...

  8. JVM内存管理------JAVA语言的内存管理概述

    转载自  JVM内存管理------JAVA语言的内存管理概述 引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上 ...

  9. JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)

    转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...

最新文章

  1. JavaScript事件与jQuery方法
  2. 如何维护关键字_SEO人如何制定工作计划?【大站】
  3. 珠海 第十届亚洲机器人锦标赛_2016年第十届亚洲机器人锦标赛在广东珠海成功举办...
  4. SAP IBASE logic of pt_equiindx
  5. C# numericUpDown控件用法总结及注意事项
  6. 决策树缺失值python_【机器学习笔记之二】决策树的python实现
  7. arcgis运行慢_ArcGIS Pro运行较慢的诊断方法
  8. 在WebBrowser中通过模拟键盘鼠标操控网页中的文件上传控件
  9. 今日看了一下广告收入,心里拔凉拔凉的。
  10. 人的五要素:自我意识、关系意识、信息、计划、行动
  11. Python利用hadoop Streaming编写的Map-Reduce程序命令运行和本地调试运行
  12. FinalShell连接VM出现channel is not opened.
  13. 日语动词变形方法全解
  14. 虚拟机怎么安装软件 Mac虚拟机怎么安装软件
  15. Linux 10个主流发行版本
  16. ubuntu20.02安装显卡驱动常见问题总结
  17. Linux起服务常用命令及实例
  18. 解读|TARS开源项目发布Go语言版本 1
  19. 设计模式详解:抽象工厂模式
  20. 用exists代替in真的好么?

热门文章

  1. 洛谷1006 传纸条
  2. Mongodb安装搭建Replica Set+Sharding集群
  3. ASP.NET中Json的处理
  4. maven小节,Nexus私服,构件打包发布,动态资源过滤,自动部署到本地或远程服务器...
  5. Java基础-特殊数据类型:枚举
  6. Python初学者之ImportError: No module named moviepy.editor 的解决办法
  7. windows下安装ElasticSearch的Head插件
  8. PCL点云库用贪婪投影三角法网格化实现点云的表面重建
  9. python中获取python版本号的方法
  10. Flask-请求上下文