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中引用的对象(栈内存中引用的对象)
  • 方法区中静态引用

转载于:https://www.cnblogs.com/developerxiaofeng/p/9214969.html

java中JVM内存管理(1)相关推荐

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

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

  2. 深入浅出 Java 中 JVM 内存管理

    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. 人大附中高中生学Python获数据挖掘竞赛一等奖,将去旷视科技实习
  2. node.js require()缓存-可能无效?
  3. [小技巧]在NTFS分区中复制文件的同时如何复制权限
  4. 基于51单片机的高频频率计的设计
  5. 变形积木装饰科技发起创始人郭辉:I'm the Business Bible
  6. 连连看java代码_连连看 - java代码库 - 云代码
  7. 算法设计之—常用算法之-分支界定法
  8. HTML5原生拖拽/拖放(drag drop)详解
  9. 2017四川省赛E题( Longest Increasing Subsequence)
  10. kafka php 教程,php 使用kafka
  11. spring源码学习
  12. android 9.0 xposed,EdXposed管理器(安卓9.0专用)
  13. JAVA创建内部类对象
  14. 达梦MPP 环境搭建
  15. 使用Pyppeteer进行gmail模拟登录
  16. matplotlib 设置坐标轴位置(spines),设置坐标别名(xticks,yticks)
  17. bigemap大地图软件功能对比分析
  18. python—基础练习2
  19. mysql 启动 错误1053:服务没有及时响应启动或者控制请求
  20. r语言electricity数据集_怎么学习用 R 语言进行数据挖掘?

热门文章

  1. 用SQL语句添加删除修改字段、一些表与字段的基本操作、数据库备份等
  2. 安装Mysql与nginx结合的小型服务
  3. 利用ASP控制WEB打印代码方法集合
  4. 搞网络都应该知道的12条基本命令
  5. linux下vim 打开文件方式
  6. 一看就懂,图解 Spring 循环依赖,写得老好了!
  7. RabbitMQ 和 Kafka 到底怎么选?
  8. Python 函数参数的分类及使用方法
  9. 怎么样让body、div占满整个浏览器的窗口
  10. Linux中如何java联网,如何在Java中运行Linux命令?