文章目录

  • 1. 什么是JVM
  • 2. JVM 内存区域划分
  • 3. JVM 类加载机制
    • 3.1 类加载过程
      • ① 加载
      • ② 验证
      • ③ 准备
      • ④ 解析
      • ⑤ 初始化
    • 3.2 双亲委派模型
  • 4. JVM 垃圾回收
    • 4.1 什么是垃圾回收
    • 4.2 Java 的垃圾回收要回收的内存是哪些
    • 4.3 回收堆上的内存,具体是回收什么
    • 4.4 垃圾回收是怎么回收的
    • 4.5 判断垃圾的算法
      • a) 引用计数算法
      • b) 可达性分析算法
    • 4.6 垃圾回收算法
      • ① 标记 - 清除 算法
      • ② 复制算法
      • ③ 标记 - 整理 算法
      • ④ 分代算法

1. 什么是JVM

JVM 是 Java Virtual Machine 的简称,意为 Java虚拟机.
虚拟机是指通过软件模拟的具有完整硬件功能的,运行在一个完全隔离的环境中的完整计算机系统.

2. JVM 内存区域划分

堆 : 放的是 new 的对象
方法区 : 放的是 类对象
栈 : 放的是局部变量
程序计数器 : 放了一个内存地址

注意事项:

  1. 堆 和 方法区 只有唯一的一份
  2. 栈和程序计数器是每个线程都有一个\
  3. 堆溢出,new的对象太多
  4. 栈溢出,无限递归

示例 :

class Student{public int Id;
}
public class Test {Student student2 = new Student();static Student student3 = new Student();public static void main(String[] args) {Student student1 = new Student();}
}

student1 是在栈里
student2 是在堆里
student3 是在方法区里

3. JVM 类加载机制

3.1 类加载过程


这是类加载的过程.

① 加载

Java虚拟机需要完成以下三件事情:
1)通过一个类的全限定名来获取定义此类的二进制字节流。
2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
3)在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

② 验证

验证刚刚的Class文件是不是一个合法的文件.

验证选项:

  1. 文件格式验证
  2. 字节码验证
  3. 符号引用验证…

③ 准备

为了类对象中的一些成员分配内存空间(静态变量),并且进行一个初步的初始化(把初始的空间设为全0).

public static int value = 333
它初始化 value 的值为0,并非333

④ 解析

Class文件中就会涉及一些字符串常量.
解析就是把这个类加载过程中,需要把这些字符串常量给替换成当前JVM内部已经持有的字符串常量的地址.

⑤ 初始化

这个阶段就是真正开始堆静态变量进行初始化.同时也会执行static代码块

3.2 双亲委派模型

在 JVM 中, 有三个类加载器(三个特殊的对象) 来负责进行这里的找文件的操作.

这里如果一个类收到了类加载的请求,它首先不会自己尝试加载这个类,而是把这个请求给委派给父亲加载器.

BootStrap 是爷爷,ExtClassLoader 是父亲,AppClassLoader 是儿子.
当收到一个类加载请求,首先从 AppClassLoader 开始查找,在查找之前会把这个请求委派给父亲ExtClassLoader,在 ExtClassLoader 开始查找之前,会把这个请求委派给父亲 BootStrap.BootStrap 没有父亲,就自己查找.
 
如果BootStrap找到了,就直接加载.如果没有找到,就回到孩子继续查找.
如果ExtClassLoader找到了,就直接加载.如果没有找到,就回到孩子继续查找
如果AppClassLoader找到了,就直接加载.如果没有找到,就抛出 ClassNotFoundException.

4. JVM 垃圾回收

4.1 什么是垃圾回收

垃圾回收(GarbageCollection,GC),顾名思义就是释放垃圾占用的空间,防止内存泄露。有效的使用可以使用的内存,对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收。

4.2 Java 的垃圾回收要回收的内存是哪些

由于栈和程序计数器的内存都是和具体的线程绑定在一起,代码块结束/线程结束,内存就自动释放了.
方法区和堆是垃圾回收机制要释放的内容.方法区进行垃圾回收比较特殊不考虑.
这里讨论的垃圾回收主要指的是上内存的回收.

4.3 回收堆上的内存,具体是回收什么

堆上的内存分为三类:

  1. 完全要使用
  2. 完全不使用
  3. 一半要使用, 一半不使用

Java 中的垃圾回收, 是以"对象"为基本单位的.一个对象不会存在被回收一半的情况.

4.4 垃圾回收是怎么回收的

垃圾回收就是 先找到垃圾,然后再回收垃圾

垃圾: 就是再也不会被使用到的对象

4.5 判断垃圾的算法

a) 引用计数算法

就相当于在对象里面增加一个引用计数器,
每当有一个地方引用它的时候,计数器就+1.
每当这个引用失效时,计数器就-1


优点 :
规则简单,实现方便,比较高效
缺点 :

  1. 空间利用率比较低(浪费空间)
    如果你一个对象很大,在程序中数目不多.此时引用计数就没有什么影响(本来一个对象就很大)
    如果你一个对象很小,在程序中数目很多,此时引用计数空间开销就很大(本来一个和对象很小,每个对象加个int)
  2. 存在循环引用的问题

b) 可达性分析算法

从一组初始的位置出发, 向下进行深度遍历, 把所有能够访问到的对象都标记为 “可达”.对应的, 不可达的对象就是垃圾.



JVM 中采取的方案. JVM 存在一个/一组线程,周期性的进行遍历,不断的找出这些不可达的对象,由 JVM 回收.

把可达性分析, 初始位置为 “GC Root”

可作为GC Roots的对象包含下面几种:

  1. 栈上的局部变量中的引用
  2. 常量池里面的引用执行的对象
  3. 方法区中, 引用类型的静态成员变量

Java的引用也可以被判定对象的生死了
四种引用:

  1. 强引用: 既能访问对象, 也能决定对象的生死
  2. 软引用: 能访问对象,但是只能一定程度的决定对象的生死
  3. 弱引用: 能访问对象,不能决定对象的生死
  4. 虚引用: 既不能找到对象, 也不能决定对象的生死.只能在对象临被回收前, 进行一些善后工作.

4.6 垃圾回收算法

① 标记 - 清除 算法

该算法分为 “标记” 和 “清除” 两个阶段:首先标记处所有需要回收的对象,在标记完成后统一回收所有被标记的对象.

缺点 :

  1. 效率问题: 标记和清除两个过程的效率都不高
  2. 空间问题: 由于回收后产生的大量的不连续的内存空间,想要申请足够的连续内存,就可能分配失败.

② 复制算法

将内存按容量划分为大小相等的两块, 每次只使用一块.当这块内存需要进行垃圾回收时,会将此区域还存活的对象复制到另一块上.

缺点 :

  1. 空间问题: 可用的内存空间只有一半
  2. 效率问题: 如果要回收的对象比较少,复制的开销就很大

③ 标记 - 整理 算法

跟标记-清除一样,只不过后续让存活的对象都向一段搬运

缺点 :
在这个搬运过程中,也是一个很大的开销,这个开销比复制算法里面复制对象的开销甚至更大

④ 分代算法

在 JVM 中, 进行垃圾回收扫描也是周期性的,这个对象每次经历了一个扫描周期, 就认为"长了一岁"
根据这个对象的年龄来堆整个内存进行分类.年龄短的对象放在一起,年龄长的对象放在一起.不同的年龄的对象,就可以采取不同的垃圾回收算法来进行处理了.

分代回收的过程:

  1. 一个新的对象, 诞生于新生代.
  2. 如果活到了一岁的对象(经历了一轮GC),就拷贝到生存区
  3. 在生存区中,对象也要经历若干轮GC.每一轮GC逃过的对象,都通过复制算法拷贝到另外的生存区里.这里的对象来回拷贝,每一轮都会淘汰掉一波对象
  4. 在生存区中,熬过一定轮次的GC之后(一般情况默认15次),这个对象仍然没有被淘汰,JVM就认为这个对象未来还会更持久的存在下去.于是就拷贝到老年代去
  5. 进入老年代的对象,JVM都认为是属于能持久存在的对象,这些对象也需要使用GC来扫描,但是扫描的频次就阿达降低了.老年代通常使用的是标记-整理算法.

特殊情况,如果这个对象特别大,就会直接进入老年代.

Java虚拟机 --- JVM相关推荐

  1. Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论

    Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...

  2. Java虚拟机JVM学习05 类加载器的父委托机制

    Java虚拟机JVM学习05 类加载器的父委托机制 类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap ...

  3. 《深入理解Java虚拟机 - Jvm高级特性与最佳实践(第三版)》阅读笔记

    <深入理解Java虚拟机>阅读笔记 本repository为<深入理解Java虚拟机 - Jvm高级特性与最佳实践(第三版)>阅读笔记,因为第一章主要讲的是Java的发展历史, ...

  4. 深入理解Java虚拟机——JVM类加载机制(类加载过程和类加载器)

    一.什么是类加载机制? 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 二.类加载的时机 类 ...

  5. Java虚拟机JVM简单理解

    Java虚拟机JVM的作用: Java源文件(.java)通过编译器编译成.class文件,.class文件通过JVM中的解释器解释成特定机器上的机器代码,从而实现Java语言的跨平台. JVM的体系 ...

  6. [java] 虚拟机(JVM)底层结构详解[转]

    [java] 虚拟机(JVM)底层结构详解[转] 本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 在以前的博客里面,我们介绍了在java领 ...

  7. Java虚拟机JVM的内部体系结构

    JVM(Java虚拟机)是一个抽象机器. 它是一个提供可以执行Java字节码的运行时环境的规范.JVM可用于许多硬件和软件平台(即JVM是平台相关的). 什么是JVM? JVM(Java虚拟机)是: ...

  8. [转载] java虚拟机 jvm 出入java栈 栈空间内存分配

    参考链接: Java虚拟机(JVM)堆栈区域 java栈空间是一块线程私有的内存空间,java堆和程序数据密切相关,那么java栈就是和线程执行密切相关.线程最基本的执行行为就是函数的调用.每次函数调 ...

  9. java虚拟机MyEclipse_Eclipse和MyEclipse运行环境java虚拟机jvm设置,自己设置jre

    Eclipse运行环境java虚拟机jvm设置,自己设置jre 浅谈Eclipse寻找JVM(JRE)的顺序机制 Eclipse也是一个普通的Java程序,因此必须有一个JRE做为运行环境. 如果你的 ...

  10. 深入理解java虚拟机 - jvm高级特性与最佳实践(第三版)_JVM虚拟机面试指南:年薪30W以上高薪岗位需求的JVM,你必须要懂!...

    JVM的重要性 很多人对于为什么要学JVM这个问题,他们的答案都是:因为面试.无论什么级别的Java从业者,JVM都是进阶时必须迈过的坎.不管是工作还是面试中,JVM都是必考题.如果不懂JVM的话,薪 ...

最新文章

  1. 对查找的结果进行删除
  2. php mysql 超时时间_php mysql超时设置方法
  3. Linus 在圣诞节想提前放假做了这些解释,哈哈哈
  4. C++单例模式:单例模式遇到多线程
  5. 组合的输出(信息学奥赛一本通-T1317)
  6. 第103天:CSS3中Flex布局(伸缩布局)详解
  7. android gradle 1.5.0,Cordova build – 无法解析com.android.tools.build:gradle:1.5.0
  8. c语言表达式10 6的结果,C语言表达式(++i)+(++i)+(++i)结果多少?
  9. Java宝典app下载
  10. 配置机器学习训练环境太麻烦?开源工具Parris说一键就搞定
  11. linux内核之dmaengine
  12. windows bat 批处理常用命令
  13. spring定时器时间表达式
  14. Arduino--DS3231时钟模块
  15. 小学数学四年级上册计算机教案,新人教版四年级上册数学教案
  16. vsftpd虚拟账户(虚拟用户,ubuntu16,舍弃虚拟用户配置文件)
  17. 35 漂亮的单页网页设计
  18. 囧囜囟囥圀圄圅圙圝圞
  19. 给你一个Pull Request的机会
  20. 磁盘的扩展卷和压缩卷显示灰色,无法使用

热门文章

  1. C#毕业设计——基于C#+asp.net+sqlserver的证券术语解释及翻译系统设计与实现(毕业论文+程序源码)——翻译系统
  2. padStart()和padEnd()
  3. Google翻译API的使用
  4. java大数据开发是做什么的
  5. Zephyr-WEST工具
  6. 【vue3 组件生命周期流程 功能】13个生命周期详解
  7. CC++编程环境搭建-四种常用开发工具(VSCode,Dev,CodeBlocks,Clion)
  8. socket编程为什么需要htons(), ntohl(), ntohs(),htons() 函数
  9. Linux编译之(1)C语言基础
  10. java从入门到精通----OOP 2