JVM架构和GC垃圾回收机制--面试

JVM架构和GC垃圾回收机制详解

JVM架构图分析

下图:参考网络+书籍,如有侵权请见谅 (想了解Hadoop内存溢出请看: Hadoop内存溢出(OOM)分类、参数调优化)

JVM被分为三个主要的子系统

(1)类加载器子系统(2)运行时数据区(3)执行引擎

1. 类加载器子系统

Java的动态类加载功能是由类加载器子系统处理。当它在运行时(不是编译时)首次引用一个类时,它加载、链接并初始化该类文件。

1.1 加载

类由此组件加载。启动类加载器 (BootStrap class Loader)、扩展类加载器(Extension class Loader)和应用程序类加载器(Application class Loader) 这三种类加载器帮助完成类的加载。

1.  启动类加载器 – 负责从启动类路径中加载类,无非就是rt.jar。这个加载器会被赋予最高优先级。

2.  扩展类加载器 – 负责加载ext 目录(jre\lib)内的类.

3.  应用程序类加载器 – 负责加载应用程序级别类路径,涉及到路径的环境变量等etc.

上述的类加载器会遵循委托层次算法(Delegation Hierarchy Algorithm)加载类文件

1.2 链接

1.  校验 – 字节码校验器会校验生成的字节码是否正确,如果校验失败,我们会得到校验错误

2.  准备 – 分配内存并初始化默认值给所有的静态变量。

3.  解析 – 所有符号内存引用方法区(Method Area)原始引用所替代。

1.3 初始化

这是类加载的最后阶段,这里所有的静态变量会被赋初始值, 并且静态块将被执行。

2. 运行时数据区(Runtime Data Area)

The 运行时数据区域被划分为5个主要组件:

2.1 方法区(Method Area)

所有类级别数据将被存储在这里,包括静态变量。每个JVM只有一个方法区,它是一个共享的资源。

2.2 堆区(Heap Area)

所有的对象和它们相应的实例变量以及数组将被存储在这里。每个JVM同样只有一个堆区。由于方法区堆区的内存由多个线程共享,所以存储的数据不是线程安全的

2.3 栈区(Stack Area)

对每个线程会单独创建一个运行时栈。对每个函数呼叫会在栈内存生成一个栈帧(Stack Frame)。所有的局部变量将在栈内存中创建。栈区是线程安全的,因为它不是一个共享资源。栈帧被分为三个子实体:

a 局部变量数组 – 包含多少个与方法相关的局部变量并且相应的值将被存储在这里。

b 操作数栈 – 如果需要执行任何中间操作,操作数栈作为运行时工作区去执行指令。

c 帧数据 – 方法的所有符号都保存在这里。在任意异常的情况下,catch块的信息将会被保存在帧数据里面。

2.4 PC寄存器

每个线程都有一个单独的PC寄存器来保存当前执行指令的地址,一旦该指令被执行,pc寄存器会被更新至下条指令的地址。

2.5 本地方法栈

本地方法栈保存本地方法信息。对每一个线程,将创建一个单独的本地方法栈。

3. 执行引擎

分配给运行时数据区的字节码将由执行引擎执行。执行引擎读取字节码并逐段执行。

3.1  解释器:

 解释器能快速的解释字节码,但执行却很慢。 解释器的缺点就是,当一个方法被调用多次,每次都需要重新解释。

编译器

JIT编译器消除了解释器的缺点。执行引擎利用解释器转换字节码,但如果是重复的代码则使用JIT编译器将全部字节码编译成本机代码。本机代码将直接用于重复的方法调用,这提高了系统的性能。

a. 中间代码生成器 – 生成中间代码

b. 代码优化器 – 负责优化上面生成的中间代码

c. 目标代码生成器 – 负责生成机器代码或本机代码

d.  探测器(Profiler) – 一个特殊的组件,负责寻找被多次调用的方法。

3.3  垃圾回收器:

收集并删除未引用的对象。可以通过调用"System.gc()"来触发垃圾回收,但并不保证会确实进行垃圾回收。JVM的垃圾回收只收集哪些由new关键字创建的对象。所以,如果不是用new创建的对象,你可以使用finalize函数来执行清理。

Java本地接口 (JNI)JNI 会与本地方法库进行交互并提供执行引擎所需的本地库。

本地方法库:它是一个执行引擎所需的本地库的集合。

JVM三大核心区域

通过一个小程序认识JVM

 package com.spark.jvm;
/*** 从JVM调用的角度分析java程序堆内存空间的使用:* 当JVM进程启动的时候,会从类加载路径中找到包含main方法的入口类HelloJVM* 找到HelloJVM会直接读取该文件中的二进制数据,并且把该类的信息放到运行时的Method内存区域中。* 然后会定位到HelloJVM中的main方法的字节码中,并开始执行Main方法中的指令* 此时会创建Student实例对象,并且使用student来引用该对象(或者说给该对象命名),其内幕如下:* 第一步:JVM会直接到Method区域中去查找Student类的信息,此时发现没有Student类,就通过类加载器加载该Student类文件;* 第二步:在JVM的Method区域中加载并找到了Student类之后会在Heap区域中为Student实例对象分配内存,* 并且在Student的实例对象中持有指向方法区域中的Student类的引用(内存地址);* 第三步:JVM实例化完成后会在当前线程中为Stack中的reference建立实际的应用关系,此时会赋值给student* 接下来就是调用方法* 在JVM中方法的调用一定是属于线程的行为,也就是说方法调用本身会发生在线程的方法调用栈:* 线程的方法调用栈(Method Stack Frames),每一个方法的调用就是方法调用栈中的一个Frame,* 该Frame包含了方法的参数,局部变量,临时数据等 student.sayHello();*/
public class HelloJVM {//在JVM运行的时候会通过反射的方式到Method区域找到入口方法mainpublic static void main(String[] args) {//main方法也是放在Method方法区域中的/*** student(小写的)是放在主线程中的Stack区域中的* Student对象实例是放在所有线程共享的Heap区域中的*/Student student = new Student("spark");/*** 首先会通过student指针(或句柄)(指针就直接指向堆中的对象,句柄表明有一个中间的,student指向句柄,句柄指向对象)* 找Student对象,当找到该对象后会通过对象内部指向方法区域中的指针来调用具体的方法去执行任务*/student.sayHello();}
}class Student {// name本身作为成员是放在stack区域的但是name指向的String对象是放在Heap中private String name;public Student(String name) {this.name = name;}//sayHello这个方法是放在方法区中的public void sayHello() {System.out.println("Hello, this is " + this.name);}
}
  1. MapReduce过程详解及其性能优化

转发:https://blog.csdn.net/aijiudu/article/details/72991993

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423394.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java中线程池的几种实现方式

1、线程池简介: 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。 假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中…

JVM架构和GC垃圾回收机制详解

JVM架构图分析 下图:参考网络书籍,如有侵权请见谅 (想了解Hadoop内存溢出请看: Hadoop内存溢出(OOM)分类、参数调优化) JVM被分为三个主要的子系统 (1)类加载器子系统(2&#xff0…

IIS不能发布asp.net 应用程序

IIS不能发布asp.net 应用程序最近在写程序的时候,突然项目经理想发布一下网站看一下做的效果当我发布的时候遇到 下面的错误::使用 XSL 样式表无法查看 XML 输入。请更正错误然后单击 刷新按钮,或以后重试。 名称以无效字符开头的…

前端学习(41):背景实现视觉差效果

首先准备三张图片 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compatible&quo…

CAS原理分析

在JDK 5之前Java语言是靠synchronized关键字保证同步的&#xff0c;这会导致有锁&#xff08;后面的章节还会谈到锁&#xff09;。 锁机制存在以下问题&#xff1a; &#xff08;1&#xff09;在多线程竞争下&#xff0c;加锁、释放锁会导致比较多的上下文切换和调度延时&…

深入理解HashMap(原理,查找,扩容)

面试的时候闻到了Hashmap的扩容机制&#xff0c;之前只看到了Hasmap的实现机制&#xff0c;补一下基础知识&#xff0c;讲的非常好 原文链接&#xff1a; http://www.iteye.com/topic/539465 Hashmap是一种非常常用的、应用广泛的数据类型&#xff0c;最近研究到相关的内容&…

uml 类图整理

1.五分钟读懂UML类图 http://www.cnblogs.com/shindo/p/5579191.html 2.UML类关系&#xff08;依赖&#xff0c;关联&#xff0c;聚合&#xff0c;组合的区别&#xff09; https://www.jianshu.com/p/eefa0b5b4922 2.1 关联 1、关联关系 关联关系又可进一步分为单向关联、…

web控件开发系列(四) 自定义控件属性(下)

控件在WEB开发时经常要用到&#xff0c;虽然有部分已经存在工具箱里&#xff0c;但有时总需要根据自己的要求&#xff0c;开发一些合适自己的控件。接上一节,已经说过了控件的属性, 例如&#xff0c;我们需要一组属性的集合时&#xff0c;这时我们需要用到的就是复杂属性了&…

23设计模式学习

1.什么设计模式 1.1模式是解决相似问题的核心1.2设计模式软件设计过程中解决一类问题的方案总结来说&#xff1a;设计模式 &#xff1a;软件设计过程中解决一类问题的一种方案&#xff1b; 2.什么是面向对象的设计模式 面向对象设计模式描述了面向对象设计过程中、特定场景下…

移植u-boot-2012.04.01到jz2440开发板

今天我给大家分享一下如何移植一个纯净的uboot到jz2440开发大版&#xff0c;通过记录学习分享&#xff0c;与大家一起进步&#xff01;&#xff01;&#xff01; 1.首先我们在uboot官网下载u-boot-2012.04.01.tar.bz2&#xff0c;建立source insight工程。将下载好的uboot通过…

温习了一下java线程状态方面的知识总结一

好长时间没有复习线程状态这块&#xff0c;读并发编程实战正好看着这块&#xff0c;顺便复习一下&#xff1a; 1.线程的五种状态&#xff1a; 2.线程五种状态的转换图&#xff1a; wait()会立刻释放synchronized(obj)中的锁以便其它线程可以执行obj.notify 但是notify() 不会立…

WinForm:进度条的实现(异步)

在WinForm中经常遇到一些费时的操作界面&#xff0c;比如统计某个磁盘分区的文件夹或者文件数目&#xff0c;如果分区很大或者文件过多的话&#xff0c;处理不好就会造成“假死”的情况&#xff0c;或者报“线程间操作无效”的异常&#xff0c;为了解决这个问题&#xff0c;可以…

移植u-boot-2012.04.01到jz2440开发板之修改代码支持NAND启动

上一篇文章我们已经修改了uboot源码使其能够正常打印输出了&#xff0c;但是输出停到了nand启动那里&#xff0c;所以这篇文章就来记录如何修改源码使uboot支持NAND启动。 原来的代码在链接时加了”-pie”选项, 使得u-boot.bin里多了”(.rel)”, “*(.dynsym)”使得程序非常大…

【C++深度剖析教程4】C++的二阶构造模式

今天学习的是C中的二阶构造模式&#xff0c;二阶构造模式只是设计模式中的简单的模式&#xff0c;是一种软件设计的方法&#xff0c;并没有我们想象的那么高深&#xff0c;设计模式也是一样&#xff0c;只不过是一系列的设计方法&#xff0c;只要我们懂得了原理&#xff0c;那么…

【C++深度剖析教程5】C++中类的静态成员函数

学习交流加&#xff08;可免费帮忙下载CSDN资源&#xff09;&#xff1a;个人微信&#xff1a; liu1126137994学习交流资源分享qq群1&#xff08;已满&#xff09;&#xff1a; 962535112学习交流资源分享qq群2&#xff08;已满&#xff09;&#xff1a; 780902027学习交流资源…

eclipse 工程中使用引入maven项目遇到maven-resources-plugin:2.6 找不到

1.开始eclipse 配置本地库 首先是从maven 官网下载maven 组件 其次是配置 maven 环境和java 配置jdk 类似这里就不做介绍了 配置完环境后修改\apache-maven-3.3.9\conf\settings.xml 中的<localRepository> 设置本地仓库 然后配置eclipse 下面图中执行较为重要&#xff…

移植uboot之修改代码支持NorFlash记录

学习交流加 个人qq&#xff1a; 1126137994个人微信&#xff1a; liu1126137994学习交流资源分享qq群&#xff1a; 962535112 今天我们的任务是修改uboot源码支持NorFlash。 上两篇关于uboot移植的文章&#xff0c;我们修改了uboot源代码&#xff0c;支持了串口的输出&#xff…

移植uboot之修改代码支持NorFlash记录续集

接着上一篇文章写的内容&#xff08;上一篇文章链接&#xff1a;移植uboot之修改代码支持NORFLASH&#xff09;&#xff0c;上一篇结尾测试flash的擦除读写功能&#xff0c;结果无法写flash&#xff0c;卡在了这里&#xff1a; 前面已经擦除成功&#xff0c;这里写内容写不进…

C#开发终端式短信的原理和方法

本文示例源代码或素材下载 简介 没发过短信的年轻人肯定是属于那种受保护的稀有动物&#xff0c;通讯发达的今天短信已经成为人们交流的重要手段&#xff0c;其中也蕴含着巨大的市场和经济利益&#xff0c;掌握短信技术的人才也受到各大公司的追捧是目前职场上耀眼的明星。本文…