面试-JVM
1.java内存模型 / java运行时数据区模型?
元空间属于本地内存 而非JVM内存
内存模型
程序计数器
1.作为字节码的行号指示器,字节码解释器通过程序计数器来确定下一步要执行的字节码指令,比如:顺序执行,选择,循环,异常处理等。
2.程序计数器属于线程私有,当线程切换有切回来的时候程序计数器还记着它之前执行到哪一行指令了,可以接着执行。
程序计数器是唯一一个不会出现 OutOfMemoryError
的内存区域,程序计算器所维护的就是下一条待执行的命令的地址,它的生命周期随着线程的创建而创建,随着线程的结束而死亡。
java虚拟机栈
可能出现两种异常:
StackOverFlowError
: 若栈的内存大小不允许动态扩展(hotspot),那么当线程请求栈的深度超过当前 Java 虚拟机栈的最大深度的时候,就抛出 StackOverFlowError
错误。
OutOfMemoryError
: 如果栈的内存大小可以动态扩展(Classic), 如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError
异常。
java虚拟机栈是线程私有的,与线程的生命周期同步,主要描述的是方法执行的内存模型。由一个个栈帧组成。
每个方法执行都会创建一个栈帧。也是先进后出的顺序。
每个栈帧包括:局部变量表、操作数栈、动态链接、方法返回地址。
https://blog.51cto.com/u_15334563/3473150
局部变量表:用来存储编译器可知的类型(基本数据类型、对象引用(reference))
操作数栈:是的方法调用的中转站,用来存放方法和执行过程产生的中间计算结果和计算过程的临时变量。
动态链接:在一个方法调用另外一个方法时,将符号引用转换为直接引用的过程。(java源文件被编译成字节码时,所有的变量、方法引用都作为符号引用保存在了Class文件的常量池里)
方法返回地址:用于存放调用该方法的pc寄存器的值,方法结束后出栈过程,恢复上层方法的栈帧信息(恢复上层方法的局部变量表、操作数栈、将返回值入调用者栈帧的操作数栈、设置PC寄存器值等,让调用者方法继续执行下去)
本地方法栈
和java虚拟栈功能类似。java虚拟机栈服务于java方法,本地方法栈服务于本地方法。也由栈帧组成,栈帧包括本地变量表、操作数栈、动态链接、出口信息。在hotspot里。本地方法栈和java虚拟栈合二为一了。
堆
堆是jvm里面最大的一块内存区域,也是垃圾回收器主要工作的场所。几乎所有的对象实例和数组都存放在堆内存里。但是有一些对象实例可以不放在堆里,而放在栈里面。因为这些对象是方法私有的,他们在方法里面被创建,但是没有逃逸出去(未返回,也未被外部引用)。
从 JDK 1.7 开始已经默认开启逃逸分析。
逃逸分析://TODO
堆内存模型:
jdk1.7及以前:堆内存主要由三部分组成:新生代、老年代、永久代组成
jdk1.8:堆内存主要由两部分组成:新生代、老年代。
而之前永久代存放的东西被元空间代替。存放到了直接内存。
“永久代与堆内存存在于连续的物理内存上,可以看作是从堆内存中拿出一部分内存作为永久代,但是两者又是互相隔离的,所以永久代称为非堆,此时永久代的大小受限于堆内存的大小,因为永久代是从堆内存拿的空间,逻辑上是与堆内存连在一起的”
为什么要用元空间取代永久代?
1.减少OOM
因为永久代配置的内存大小是有限的(jvm为永久代设置了一个大小),如果动态生成很多class的时候,很有可能出现java.lang.OutOfMemoryError:PermGen space错误。
2.方便合并 HotSpot 和 JRockit 的代码,Rockit没有永久代的概念。
堆内存容易发生的OutOfMemoryError
异常:
java.lang.OutOfMemoryError: GC Overhead Limit Exceeded
: 当 JVM 花太多时间执行垃圾回收并且只能回收很少的堆空间时,就会发生此错误。java.lang.OutOfMemoryError: Java heap space 新建对象,内存空间不够的时候。
方法区(是逻辑区域)
永久代:
1.7之前 字符串常量池、静态变量、类信息、运行时常量池、JIT代码缓存
1.7 类信息、运行时常量池、JIT代码缓存 (字符串常量池、静态变量被移到了堆了)
1.8没了 被元空间取代了
JDK 1.7 为什么要将字符串常量池移动到堆中?
主要是因为永久代(方法区实现)的 GC 回收效率太低,只有在整堆收集 (Full GC)的时候才会被执行 GC。Java 程序中通常会有大量的被创建的字符串等待回收,将字符串常量池放到堆中,能够更高效及时地回收字符串内存。
方法区常用参数有哪些?
JDK 1.8 之前永久代还没被彻底移除的时候通常通过下面这些参数来调节方法区大小。
-XX:PermSize=N //方法区 (永久代) 初始大小
-XX:MaxPermSize=N //方法区 (永久代) 最大大小,超过这个值将会抛出 OutOfMemoryError 异常:java.lang.OutOfMemoryError: PermGen
相对而言,垃圾收集行为在这个区域是比较少出现的,但并非数据进入方法区后就“永久存在”了。
JDK 1.8 的时候,方法区(HotSpot 的永久代)被彻底移除了(JDK1.7 就已经开始了),取而代之是元空间,元空间使用的是直接内存。下面是一些常用参数:
-XX:MetaspaceSize=N //设置 Metaspace 的初始(和最小大小)
-XX:MaxMetaspaceSize=N //设置 Metaspace 的最大大小 默认unlimited
与永久代很大的不同就是,如果不指定大小的话,随着更多类的创建,虚拟机会耗尽所有可用的系统内存。
直接内存
不属于jvm运行时数据区,也不是jvm规范中定义的内存区域。但是会被频繁使用,也可能出现OOM. 不受jvm内存的限制,但是会收到本机总空间内存和处理器寻址空间的限制。
NIO的应用
NIO引入的channel和buffer的方式,可以直接使用本地函数分配堆外内存,然后通过堆中的DirectByteBuffer 对象作为这块内存的引用进行操作,避免了java堆和本地堆来回复制数据,提高了性能。
2.对象的创建过程
类加载检查->分配内存->设置默认初始值->设置对象头->执行init方法
3.对象的内存布局
对象头:第一部分用于存储对象自身的运行时数据(哈希码、GC 分代年龄、锁状态标志等等),另一部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
实例数据
对齐填充:Hotspot 虚拟机的自动内存管理系统要求对象起始地址必须是 8 字节的整数倍
4.对象的访问定位
句柄:局部变量表里面reference保存句柄的地址,根据堆里面的句柄(包含对象实例数据地址和对象类型数据地址),找堆里的实例数据和方法区的类信息->修改对象信息,不用修改栈
直接指针:局部变量表里面reference保存对象的地址,直接找到堆里面的对象实例数据,再从堆里面对象类型数据的指针找方法区的类信息->查找速度快
面试-JVM的更多相关文章
- java面试——jvm
背景:用来总结java面试过程中与jvm相关的问题. 垃圾回收以及优化总结 <JVM 垃圾回收器工作原理及使用实例介绍> 介绍常用的垃圾回收算法,垃圾收集器,垃圾收集器相关的调试参数. J ...
- 【面试 JVM】【第六篇】JVM调优
六部分内容: 一.内存模型 1.程序计数器,方法区,堆,栈,本地方法栈的作用,保存那些数据 可以画个大图出来,很清晰 jvm内存模型主要指运行时的数据区,包括5个部分. 栈也叫方法栈,是线程私有的,线 ...
- 不止面试—jvm类加载面试题详解
面试题 带着问题学习是最高效的,本次我们将尝试回答以下问题: 什么是类的加载? 哪些情况会触发类的加载? 讲一下JVM加载一个类的过程 什么时候会为变量分配内存? JVM的类加载机制是什么? 双亲委派 ...
- [jvm][面试]JVM 调优总结
https://blog.csdn.net/wfh6732/article/details/57422967 堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-b ...
- 不止面试-JVM垃圾回收面试题详解
第一部分:面试题 本次分享我们将尝试回答以下问题: GC 是什么? 为什么要有 GC? 简单说一下java的垃圾回收机制. JVM的常见垃圾回收算法有哪些? 为什么要使用分代回收机制? 如何判断一个对 ...
- Java面试- JVM 内存模型讲解
经常有人会有这么一个疑惑,难道 Java 开发就一定要懂得 JVM 的原理吗?我不懂 JVM ,但我照样可以开发.确实,但如果懂得了 JVM ,可以让你在技术的这条路上走的更远一些. JVM 的重要性 ...
- java面试-JVM内存结构
一.JVM内存结构 二.类加载(classLoader)机制 java中的ClassLoader详解 java类加载机制面试题 java类加载机制面试题 虚拟机把描述类的数据从Class文件加载到内存 ...
- java面试-JVM常用的基本配置参数有哪些?
1.-Xms 初始大小内存,默认为物理内存 1/64,等价于 -XX:InitialHeapSize 2.-Xmx 最大分配内存,默认为物理内存的 1/4,等价于 -XX:MaxHeapSize 3. ...
- java面试-JVM调优和参数配置,如何查看JVM系统参数默认值
一.JVM的参数类型: 1.标配参数: java -version java -help 2.X参数: -Xmixed 混合模式(先编译后执行) -Xint 解释执行 -Xcomp 第一次使用就编译 ...
- 面试~jvm(JVM内存结构、类加载、双亲委派机制、对象分配,了解垃圾回收)
一.JVM内存结构 ▷ 谈及内存结构各个部分的数据交互过程:还可以再谈及生命周期.数据共享:是否GC.是否OOM 答:jvm 内存结构包括程序计数器.虚拟机栈.本地方法栈.堆.方法区:它是字节码运行时 ...
随机推荐
- openstack 私有云
Openstack 私有云 官网:www.openstack.com 关于它的历史,网上都可以搜索到,这里不做细讲. 本章主要对openstack的基础部署做详细了解 说到openstack,就要知道 ...
- unix:///var/run/supervisor.sock no such file报错解决办法
报错 unix:///var/run/supervisor.sock no such file 原因 /var/run/supervisor.sock已被清理. 解决办法 关闭supervisor:p ...
- Wps调用dll操作Excel表格转PDF
起始原因:wps编辑创建的文档在microsoft office 中打开,会报内容存在异常是否恢复,因此wps文件被微软设定为破损文件,无法对原有文档进行操作运行,故在此使用wps对Excel进行操作 ...
- TypeScript 对象
TypeScript 对象 对象是包含一组键值对的实例. 值可以是标量.函数.数组.对象等,如下实例: var object_name = { key1: "value1", // ...
- 动画图解 Git 的 10 大命令
原文地址:https://dev.to/lydiahallie/cs-visualized-useful-git-commands-37p1 原文作者:Lydia Hallie 前言 尽管 Git 是 ...
- hadoop单机测试环境安装(简)
1.下载hadoop官网就可以下载.可以直接搜hadoop , 其实可以直接查看官网的版主文档搭建https://hadoop.apache.org/docs/stable/hadoop-proj ...
- django自定义管理类的save model和delete model记一次进一步了解
业务背景: 最近在写一个个人博客网站,文章分类是一个自关联的两层分类.希望在点开分类时,显示一级分类.一级分类下的所有二级分类以及每个二级分类有多少个文章.最简单办法就是关联查询,查询出所有二级分类, ...
- PgBouncer连接池工具
PgBouncer是为PostgreSQL提供的轻量级连接池工具,作用如下:1,能够缓存和PostgreSQL的连接,当有连接请求进来的时候,直接分配空闲进程,而不需要PostgreSQL fork出 ...
- Java-String常用API
返回值类型 方法 用途 备注 char charAt(int index) 返回 char指定索引处的值. int compareTo(String anotherString) 按字典顺序比较两 ...
- 1、PyTorch基本操作
一.简介 简单介绍PyTorch框架,基本使用和安装方法.Torch是什么?一个火炬!其实跟Tensorflow中Tensor是一个意思,就是说,有一批数据,无论是图像数据还是文本数据或数值数据,都需 ...