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选项。

最新文章

  1. Pramp mock interview (4th practice): Matrix Spiral Print
  2. jQuery的deferred对象详解
  3. 通过nginx代理之后,获取客户端ip
  4. python编写telnet登陆出现TypeError:&#39;str&#39; does not support the buffer interface
  5. JellyViewPager
  6. (转)Asp.net的HttpCookie写入汉字读取时为乱...
  7. 简易 Ajax 入门案例
  8. Java8 lamda表达式快速上手
  9. 转自知乎(JAVA后台开发可以纯粹用JAVA SE吗?)
  10. fastdfsDemo
  11. Linux中修改环境变量及生效方法(永久、临时)环境变量查看
  12. ZXX43大神实现的软渲染
  13. pragma comment的使用 pragma预处理指令详解
  14. Mybatis 返回插入的主键
  15. yii CFormModel中的rules验证机制
  16. 【MySQL学习杂记】 2017年7月13日
  17. 第39次Scrum会议(12/5)【欢迎来怼】
  18. 【DataGuard】部署Data Guard相关参数详解 (转载)
  19. H3C路由器和交换机的一些记录
  20. vue服务端渲染缓存应用

热门文章

  1. Jackson转换为Collection、Array
  2. Nodejs ORM框架Sequelize(模型,关联表,事务,循环,及常见问题)
  3. iOS block的用法 by -- 周傅琦君
  4. mybatis中的#和$的使用规范
  5. 浅谈Java之反射
  6. Solution -「LOCAL」画画图
  7. suse 12 升级 OpenSSH-7.2p2 到 OpenSSH-8.4p1
  8. 从命令模式的维度理解Spring 之Application Event
  9. java POI 导出到word文档 (附工具类)
  10. PentestBOX教程