1、什么是运行时数据区?

1、什么是运行时数据区

​ javac 指令:编译java文件生成class文件

​ java指令:运行class文件即将数据放到jvm中

​ class文件运行,后将不同的数据放到jvm中不同的位置这就是运行时数据区的由来

2、运行时数据区为什么要这么划分

1、class文件中到底有多少种数据类型,即JVM的整体分析

有对象,常量、静态变量、普通成员变量、方法、局部变量、父类,XXX

怎么划分?为什么要这样划分?

1、The pc Register

	<u>4、计数器(存储当前线程执行方法的记录,下次接着下去,不用从头开始。)</u>

2、java Virtual Machine Stacks

3、java虚拟机栈:

一个线程-- > 表示一个java虚拟机栈。

方法的执行,可以通过压栈的方式 --> 方法对应栈帧,方法中:返回地址、局部变量、操作数

3、Heap

1、堆:存储对象【包括普通成员变量】/数组 如:new Person() class class==

4、Method Area

2、方法区:类的信息【创建时间,元数据信息】、常量、静态变量、即时编译器编译之后的代码

堆和方法区都是线程共享,由于其他线程共享也就是说是线程不安全。

5、Run-time constant pool

6、属于方法区的一部分

6、Native Method Stacks

5、如果不是Native(本地)方法,那就是用来存储运行到那个方法的位置。

3、方法的执行和java虚拟机栈详解

jvm整体图:

1、方法区的别名:

方法区,包含了运行时常量池

Method Area 方法区

​ JDK1.7 之前 ---> Perm Space 永久代

​ JDK1.8 之后 --> MetaSpace 元空间

2、java虚拟机,运行压栈的过程

/*java文件的方法*/
public static int calc(int op1,int op2) {
op1=3;
int result =op1+op2;
return result;
} /*生成的class文件*/
public static int calc(int,int);
Code:
0: iconst_3
1: istore_0 # 3这个数值从操作数栈中弹出来
2:iload_0
3: iload_1
4: iadd
5: istore_2
6: iload_2
7: ireturn

4、垃圾回收器和垃圾回收算法

​ 垃圾回收

​ 垃圾判断:

​ 垃圾回收算法:复制 标记-整理

我有一个块内存区域

1、原因

java进程启动时候,有一个initiaHeapSize,我是可以跟计算机要一个空间的,进行这个进程的数据保存

initiaHeapSize = 100M --> 有一块100M的物理内存,可以向计算机要内存的。

我有一块内存区域,存着存着,发现不够用了,怎么办? 不够用了将会报错--->OutOfMemoryError

万一这个内存区域中,有些数据已经彻底没用了,我们把它称作垃圾,对应的垃圾回收算法对其进行回收

2、内存模型

  1. 向计算机获取一个内存,即内存模型
  2. 内存分为:方法区,堆(保存对象)
  3. 堆又分为:老年代、新生代(保存对象满触发GC垃圾回收,删除垃圾对象,老年区和新生代的界限是15次GC,若还存在就放到老年区。)

  1. 相对于新生代而言,老年代占用空间更大,触发GC的时间更长,因此尽量减少从新生代中放对象到老年区。

    因此需要一个缓冲,将新生代分为两个部分:Eden(生成新对象放在这里),Suvivor(在Eden的GC处理后的对象放到Suvivor中,Suvivor在GC后才放到老年区

  1. Suvivor中由于有些零碎的空间,但加进来的对象需要相连的空间才能存放,所以Suvivor有分为:两个Suvivor:From 、to,每时每刻永远有一块是空的,永远有一块是满的。

  2. Suvivor中from和to可以相互转换(每时每刻都已一个是空的),如下图:

3、问题:如果Eden 占80M,S0 From 占10M, S1 To 占10M。那是不是意味着没时每刻都已10%的空间是浪费的。

​ 没错,我们就是要用这样的浪费来,获取50%的连续。

4、问题:什么样的对象才算是垃圾?

  1. 引用法:

    如果是A引用B,B引用A,相互引用那么这两者永远都不会成为垃圾,永远都会占用内存空间,这样不合适。

  1. 可达性分析:有GC root出发

回收 -->

4、回收算法:用一定的算法的方式去回收这些垃圾 3种

1、标记-清除

找出内存需要回收的对象,并且把它们标记出来

此时堆中所有的对象都会被扫描一遍,从而才能确定需要回收的对象,比较耗时。

清除垃圾对象

弊端:比较耗时(需要扫描真个内存空间,然后清除垃圾),空间碎片(不连续)

2、复制标记:

耗时(是将存活的对象移动到,另一个区间的时间)

3、标记整理

将存活的对象,移动

堆:Old Young(Eden、S0和S1)

到底哪个算法用在哪个区域呢?

不同的代用不同的垃圾回收算法

Young区,复制--->前提条件:每次垃圾回收 存活的对象都比较少 ---> 复制算法

​ 绝大多数的对象都被回收掉 --> Eden和Eden(S0 From和S1 To)

Old区呢?

​ 一般是存活时间比较长,意味着很难被回收 ---> 标记-整理、标记清除

4、会不会要我去设计垃圾回收算法呢?

1、落地垃圾回收算法

垃圾收集器(常用的G1处理器)

2、G1垃圾收集器的过程

  1. 初识标记

    使用一个垃圾回收线程,进行初识标记,注意此时其他用户线程暂定了

    标记的是什么样的对象是垃圾:标记一下GC Roots能够直接关联到的对象,Stop the world

  2. 并发标记

    从GC Roots触发可达性 存活的对象

  3. 最终标记

    最终标记 再次标记 many GC Threads

  4. 筛选回收

    回收垃圾对象 Stop the world

5、评价一个垃圾收集器的好坏的标准:

  1. 吞吐量 吞吐量越高 越好
  2. 停顿时间 停顿时间 越低越好

6、减少GC的频率 -----G1

1、适当地增加对内存空间 (这样存放对象的空间变大,GC执行的时间变长)

2、合理的设计G1垃圾收集器的停顿时间 (一般默认都回收一定的停顿时间,可以增加)

3、垃圾回收的临界线

-XX:InitiatingHeapOccupancPercent = 50 (如一般到占内存的40%,就触发GC垃圾回收,可以设置到50%)

4、增加垃圾回收线程数量(增加线程回收,空出内存)

-XX:ConGCThreads =10

Young GC:可以称为 Minor GC

old GC:可以称为 Major

也就是:

Young + Old ===>(等同于) Minor GC + Major GC ===> Full GC

老年区触发的GC 是Full GC

这就是JVM

JVM面试?

1、说一下jvm的主要组成部分?即作用?

  1. 类加载器:把java代码转换成字节码
  2. 运行数据区:把字节码加载到内存中(把文件放到响应的区间,如:变量、方法、常量... 放到响应的位置。)
  3. 执行引擎:有特定命令解析器执行引擎,字节码翻译成底层系统指令,在交由cpu执行。
  4. 交给cpu执行过程中,需要调用其他语言的本地库接口来实现真个程序的功能

2、说一下jvm运行时数据区域?

  1. 程序计数器:记录当前程序运行到哪个字节码解释器工作。

  2. java虚拟机栈:描述java的方法执行的内存模型。

  3. 本地方法栈:为虚拟机使用到的Native方法服务,本地方法使用的语言、方式、数据结构没有强制要求。

  4. java堆:jvm最大一块内存区域,被所有线程共享。

  5. 方法区:是一个共享区域,存储已被虚拟机加载的类信息,常量(fianl)、静态变量(static),JIT(即时编译器)编译后的代码等数据。

    运行时常量池。

3、栈和堆的区别?

1、栈内存是一片内存区域存储局部变量(索引)。堆内存存储数组和对象

2、栈内变量有自己的作用域,一旦离开就被释放。堆实体不会被释放,但会被当成垃圾回收

3、栈内存更新速度快于堆内存。

4、队列和栈是什么?有什么区别?

队列(Queue):是限定只能在表的一段进行插入另一端删除操作的线性表

栈(Stack):是限定只能在表的一段进行插入和删除操作的线性表

规则:

队列:先进先出

:先进后出

遍历数据速度:

​ 队列:基于地址指针遍历,同头部或尾部进行,遍历过程不影响数据结构,遍历速度快。

​ 栈:只能从顶部取数据。需要数据开闭临时空间,保持数据在便利签一致性。

5、类加载的执行过程?

加载:查找相关路径的class文件。

检查:检查class文件的正确性

准备:给类的静态变量分配内存空间

解析:虚拟机将常量池中的符号引用替换成直接引用的过程

初始化:堆静态变量和静态代码块执行初始化工作。

6、jvm有哪些垃圾回收算法?

判断对象是否存活:引用计算算法、可达性分析

1、标记-清除

2、标记-整理

3、复制算法

4、分代算法

7、jvm有哪些垃圾回收器?

Serial:最老的单线程,(运行垃圾收集线程时,必须停止所有工作线程)

ParNew:是Serial的多线程版本(工作是也要停止所有工作线程)

CMS :一种以获得最短停顿时间为目标的收集器,

G1:一种兼顾吞吐量和停顿时间的GC实现,是JDK9以后默认的GC选项。

jvm初步理解的更多相关文章

  1. 谈谈对JVM的理解

            JVM可谓是学习JAVA基础中的基础了,但仍有不少同学对JVM概念还是比较模糊,甚至没有听说过,对java的理解也只是在基础语法 层面,本文就将对JVM进行初步介绍,因篇幅所限,只能介 ...

  2. javascript 原型及原型链的初步理解

    最近折腾了好久,终于是把js里面的原型和原型链做了个初步的理解: 在这里,我打个比喻: 我(child),我妈constructor(构造函数)生了我:别人问我老妈跟谁生的我,于是此时我妈会指向我爸爸 ...

  3. Spring学习笔记--环境搭建和初步理解IOC

    Spring框架是一个轻量级的框架,不依赖容器就能够运行,像重量级的框架EJB框架就必须运行在JBoss等支持EJB的容器中,核心思想是IOC,AOP,Spring能够协同Struts,hiberna ...

  4. Graph Cuts初步理解

    一些知识点的初步理解_8(Graph Cuts,ing...) Graph cuts是一种十分有用和流行的能量优化算法,在计算机视觉领域普遍应用于前背景分割(Image segmentation).立 ...

  5. JVM如何理解Java泛型类(转)

    一个很典型的泛型(generic)代码.T是类型变量,可以是任何引用类型: public class Pair<T>{ private T first=null; private T se ...

  6. JVM如何理解Java泛型类

    //泛型代码 public class Pair<T>{ private T first=null; private T second=null; public Pair(T fir,T  ...

  7. 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感

    关键字:名称,名称空间,引用,指针,指针类型的指针(即指向指针的指针) 我读完后的理解总结: 1. 我们知道,python中的变量的赋值操作,变量其实就是一个名称name,赋值就是将name引用到一个 ...

  8. JVM深入理解

    JVM深入理解 一.JVM介绍 JVM应用百度百科的原话是: JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过 ...

  9. springBoot(1)---springboot初步理解

    springboot初步理解 在没有用SpringBoot之前,我们用spring和springMVC框架,但是你要做很多比如: (1)配置web.xml,加载spring和spring mvc 2) ...

随机推荐

  1. 隐式意图&显示意图

    1 隐式意图     通过指定一组动作或者数据 开启activity   2 显示意图    通过指定具体包名和类名 开启activity       总结    (1)显示意图更加安全一些    ( ...

  2. centOs编译安装php7.2支持微擎php扩展

    发现yum安装许多坑 于是只好编译安装 第一步得到镜像地址 在      https://www.php.net/downloads.php     有的地址比较慢,需要耐心等待 cd /usr/lo ...

  3. rust 实战 - 实现一个线程工作池 ThreadPool

    如何实现一个线程池 线程池:一种线程使用模式.线程过多会带来调度开销,进而影响缓存局部性和整体性能.而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务.这避免了在处理短时间任务时创建与销毁线 ...

  4. python 异常捕捉总结

    Process finished with exit code -1 错误 执行代码 pycharm2020.1中手动中断程序,可是却捕捉不了中断异常,并且输出Process finished wit ...

  5. 【SCOI2007】组队(单调性)

    题目链接 大意 给定\(N\)个人与三个常量\(A,B,C\),每个人有两个属性:\(Hi\),\(Vi\). 现要让你选些人出来,定义\(Hmin\)为选出来的这些人中最小的\(Hi\)值,\(Vm ...

  6. Docker使用Dockerfile构建新的镜像

    构建镜像步骤; 1.创建Dockerfile文件,该文件是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明. vim Dockerfile //每一个指令都会在镜像上创建一个新 ...

  7. C#操作读写INI配置文件

    一个完整的INI文件格式由节(section).键(key).值(value)组成.示例如:[section]key1=value1key2=value2; 备注:value的值不要太长,理论上最多不 ...

  8. SpringBoot是如何做到自动装配的

    背景 众所周知,如下即可启动一个最简单的Spring应用.查看@SpringBootApplication注解的源码,发现这个注解上有一个重要的注解@EnableAutoConfiguration,而 ...

  9. const 和指针之间的姻缘

    const和指针到底有何姻缘呢? char const *p = NULL; //char const 和 const char 是一样的,p 是一个指向常整型的指针变量 ,指针变量的值不能改变 ch ...

  10. 神奇!这款 Vue 后台框架居然不用手动配置路由

    前言 做 Vue 开发脱离不了路由,尤其是中大型项目,页面多且杂,在配置路由的时候总是会变得逐渐暴躁,因为费时,并且又没有什么太多技术含量,总觉得是在浪费时间. 另外如果接手了别人的项目,当业务有变更 ...