文档章节

简述JVM、GC

涅槃Ls
 涅槃Ls
发布于 2017/04/09 18:49
字数 1971
阅读 52
收藏 2
点赞 0
评论 0

一、JVM

    Java Virtual Machine,Java虚拟机。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。

二、JRE、JVM、JDK

    JRE(Java Runtime Environment),也就是Java平台。所有的Java程序都要在JRE下才能运行。JDK的工具也是Java程序,也需要JRE才能运行。为了保持JDK的独立性和完整性,在JDK的安装过程中,JRE也是安装的一部分。所以,在JDK的安装目录下有一个名为jre的目录,用于存放JRE文件。

    JVM(Java Virtual Machine)是JRE的一部分,jvm有自己完善的硬件架构,如处理器,堆栈,寄存器等,还有相应的指令系统,java语言最重要的特点就是跨平台运行,使用jvm就是为了支持与操作系统无关。

    JDK(Java Development Kit)是程序开发者用来编译,调试java程序用的开发工具包。

三、JVM执行程序的过程

    JVM是Java程序运行的容器,负责与操作系统的交互,用来屏蔽操作系统环境,提供一个完整的Java运行环境,但是他同时也是操作系统的一个进程,因此也有自己的运行生命周期,也有自己的代码和数据空间。JVM执行程序的过程有以下三点

  • 1、加载.class文件
  • 2、管理并分配内存
  • 3、执行垃圾收集GC

四、JVM生命周期

4.1、jvm实例对应了一个独立运行的java程序,是进程级别

  • 启动:启动一个java程序时,一个jvm实例就产生了,任何一个拥有main()的class都可以作为jvm实例运行的起点;
  • 运行:main() 作为该程序初始线程的起点,任何其他线程均由该线程启动。jvm内部有2中线程:守护线程和非守护线程。main() 属于非守护线程。守护线程是jvm自身使用,java程序也可以表明自己创建的线程是守护线程;
  • 消亡:当程序中的所有非守护线程终止时,jvm才退出;若安全管理器允许,程序也可以使用Runtime类或者System.exit()来退出。

4.2、jvm执行引擎实例则对应了属于用户执行程序的线程,是线程级别的

五、JVM体系结构

 

    

  • .类加载器(用来装载.class文件)
  • .执行引擎(执行字节码,或者执行本地方法)
  • .运行时数据区(方法区.堆.java栈.pc寄存器.本地方法栈)

六. JVM运行时数据区

    

  • 第一块:PC Register
    • pc寄存器是用于存储每个线程下一步执行的jvm指令,如方法是native的,则pc寄存器中不存储任何消息
  • 第二块:JVM Stack
    • jvm栈是线程私有的,每个线程创建的同时都会创建jvm栈
    • jvm栈中存放的为当前线程中局部基本类型变量
    • 八种基本类型:boolean、char、byte、short、int、long、float、double
  • 第三块:JVM Heap
    • 它是JVM用来存储对象实例以及数组值的区域,可以认为Java中所有通过new创建的对象的内存都在此分配,Heap中的对象的内存需要等待GC进行回收。
    • 所有类实例和数组的内存均从此处分配

6.1、内存模型

    JVM Heap是运行时数据区域,所有类实例和数组的内存均从此处分配。

    JVM主要管理两种类型内存:

  • 堆内存(Heap Memory)是在 Java 虚拟机启动时创建;
    • 简单来说,堆是Java代码可及的内存,留给开发人员使用的;
  • 非堆内存(Non-heap Memory)是在JVM堆之外的内存;
    • 非堆是JVM留给自己用的,包含方法区、JVM内部处理或优化所需的内存,如:
      • JITCompiler,Just-in-time Compiler,即时编译后的代码缓存);
      • 每个类结构(如运行时常数池、字段和方法数据);
      • 方法和构造方法的代码;
      • ......
  • 其它(Other)存放JVM 自身代码等;

七、GC/Garbage Collection

7.1、基本原理

    将内存中不再被使用的对象进行回收

    GC中用于回收的方法称为收集器,由于GC需要消耗一些资源和时间,Java在对对象的生命周期特征进行分析后,按照新生代、旧生代的方式来对对象进行收集,以尽可能的缩短GC对应用造成的暂停

  • 对新生代的对象的收集称为minor GC;
  • 对旧生代的对象的收集称为Full GC;
  • 程序中主动调用System.gc()强制执行的GC为Full GC。

7.2、JVM对象的引用类型

  • 强引用:默认引用,这个对象的实例没有其他对象引用,GC时才会被回收;
  • 软引用:一种比较适合于缓存场景的应用(只有在内存不够用的情况下才会被GC);
  • 弱引用:在GC时一定会被GC回收;
  • 虚引用:由于虚引用只是用来得知对象是否被GC;

7.3、如何判断一个变量是否该被回收

    当可用内存数量较低时,Sun版本的垃圾回收器才会被激活。

    当堆栈或静态存储区没有对这个对象的引用时,它就应该被回收了。

    有两种方法来知道这个对象有没有被引用:

  • 第一种是遍历堆上的对象找引用;
    • 实现方式是"引用计数法",意思就是当有引用连接至对象时,引用计数加1,当引用离开作用域或被置为null时,引用计数减1,这种方法有个缺陷,如果对象之间存在循环引用,可能会出现"对象应该被回收,但引用计数却不为零"的情况。
  • 第二种是遍历堆栈或静态存储区的引用找对象;

八、GC基本建议

  1. 最基本的建议就是尽早释放无用对象的引用。大多数程序员在使用临时变量的时候,都是让引用变量在退出活动域(scope)后,自动设置为 null,我们在使用这种方式时候,必须特别注意一些复杂的对象图,例如数组,队列,树,图等,这些对象之间有相互引用关系较为复杂。对于这类对象,GC 回收它们一般效率较低。如果程序允许,尽早将不用的引用对象赋为null,这样可以加速GC的工作;
  2. 尽量少用finalize函数。finalize函数是Java提供给程序员一个释放对象或资源的机会。但是它会加大GC的工作量,因此尽量少采用finalize方式回收资源;
  3. 如果需要使用经常使用的图片,可以使用soft应用类型。它可以尽可能将图片保存在内存中,供程序调用,而不引起OutOfMemory;
  4. 注意集合数据类型,包括数组,树,图,链表等数据结构,这些数据结构对GC来说,回收更为复杂;
  5. 另外,注意一些全局的变量,以及一些静态变量。这些变量往往容易引起悬挂对象(dangling reference),造成内存浪费;
  6. 当程序有一定的等待时间,程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。使用增量式GC可以缩短Java程序的暂停时间。

 

 

© 著作权归作者所有

共有 人打赏支持
涅槃Ls

涅槃Ls

粉丝 6
博文 11
码字总数 40988
作品 0
深圳
QA/测试工程师
《成神之路-基础篇》JVM——垃圾回收(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是[《成神之路系列文章》][1]的第一篇,主要是关于JVM的一些介绍。 持续更新中 Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收 ...

⋅ 05/05 ⋅ 0

Java 面试知识点解析(三)——JVM篇

前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大部...

我没有三颗心脏 ⋅ 05/16 ⋅ 0

ThreadLocal可能引起的内存泄露

  threadlocal里面使用了一个存在弱引用的map,当释放掉threadlocal的强引用以后,map里面的value却没有被回收.而这块value永远不会被访问到了. 所以存在着内存泄露. 最好的做法是将调用thr...

天天顺利 ⋅ 06/15 ⋅ 0

升级到JDK9的一个BUG,你了解吗

概述 前几天在一个群里看到一个朋友发了一个demo,说是JDK的bug,昨天在JVM的一个群里又有朋友发了,觉得挺有意思,分享给大家,希望大家升级JDK的版本的时候注意下是否存在这样的代码,如果...

你假笨 ⋅ 06/06 ⋅ 0

甲骨文开源Java 性能监控调试工具 JMC

JMC (Java Mission Control) 是Oracle开源的Java 性能监控调试工具, 源自 JRockit JVM , 主要由三个组件构成:Java 进程浏览器、JMX 控制台和 Java Flight 记录器。 主要特性: Java 进程浏览...

marsdream ⋅ 05/07 ⋅ 0

面试中关于Java虚拟机(jvm)的问题看这篇就够了

最近看书的过程中整理了一些面试题,面试题以及答案都在我的文章中有所提到,希望你能在以问题为导向的过程中掌握虚拟机的核心知识。面试毕竟是面试,核心知识我们还是要掌握的,加油~~~ 下面...

snailclimb ⋅ 05/12 ⋅ 0

《成神之路-基础篇》JVM——JVM参数及调优(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是[《成神之路系列文章》][1]的第一篇,主要是关于JVM的一些介绍。 持续更新中 JVM参数及调优 JVM实用参数系列 成为Java GC专家(5)...

⋅ 05/05 ⋅ 0

重磅!Java 性能监控调试工具 JMC 宣布开源

JRockit JVM 创始人之一、Oracle Java 产品组成员 Marcus Hirt 昨日在其博客上宣布,Java Mission Control(JMC)的源代码已正式开源。 JMC 是源自 JRockit JVM 的一套监控和管理工具,Oracl...

王练 ⋅ 05/07 ⋅ 6

JVM性能调优实践——JVM篇

前言 在遇到实际性能问题时,除了关注系统性能指标。还要结合应用程序的系统的日志、堆栈信息、GClog、threaddump等数据进行问题分析和定位。关于性能指标分析可以参考前一篇JVM性能调优实践...

lijingyao8206 ⋅ 05/24 ⋅ 0

JAVA虚拟机 JVM 详细分析 原理和优化(个人经验+网络搜集整理学习)

JVM是java实现跨平台的主要依赖就不具体解释它是什么了 ,简单说就是把java的代码转化为操作系统能识别的命令去执行,下面直接讲一下它的组成 1.ClassLoader(类加载器) 加载Class 文件到内...

小海bug ⋅ 06/14 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

开启Swarm集群以及可视化管理

在搭建的两台coreos服务器上开启swarm集群 前置条件: docker均开启2375端口 同一个局域网内 主服务器上安装Portainer容器 安装Portainer容器执行: docker run -d -p 9000:9000 --restart=a...

ykbj ⋅ 27分钟前 ⋅ 0

单例设计模式

1、单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例 2、饿汉式单例类 在这个类被加载时,静态变量instance会被初始化,此时类的私有构造子会被调用 饿汉式是典型...

职业搬砖20年 ⋅ 32分钟前 ⋅ 0

前端基础(四):前端国际规范收集

字数:1142 阅读时间:5分钟 前言 由于前端技术的灵活性和杂乱性,导致网上的许多解决方案不够全面甚至是完全错误,容易起到误导作用。所以,我对搜索到的解决方案往往是存疑态度。那么,如何...

老司机带你撸代码 ⋅ 34分钟前 ⋅ 0

Failed to open/create Network-VirtualBox Host-Only

虚拟机版本 : Oracle Vm VirtualBox 5.2.12 报错时机:开网卡二,重启虚拟机报错 "Failed to open/create the internal network 'HostInterfaceNetworking-VirtualBox Host-Only Ethernet Ada......

p至尊宝 ⋅ 37分钟前 ⋅ 0

三分钟学会如何在函数计算中使用 puppeteer

摘要: 使用 puppeteer 结合函数计算,可以快速的构建弹性的服务完成各种功能,包括:生成网页截图或者 PDF、高级爬虫,可以爬取大量异步渲染内容的网页、模拟键盘输入、表单自动提交、登录网...

阿里云云栖社区 ⋅ 41分钟前 ⋅ 0

springMVC接收表单时 Bean对象有Double Int Char类型的处理

前台ajax提交表单price为double类型 后台controller就介绍不到 400错误 前台 实体类: public class ReleaseMapIconConfig{ private String id; private long maxValue; private long minVal......

废柴 ⋅ 43分钟前 ⋅ 0

ZOOKEEPER安装

工作需要在ubuntu上配置了一个zookeeper集群,有些问题记录下来。 1. zookeeper以来java,所以首先要安装java。但是ubuntu系统有自带的jdk,需要通过命令切换java版本: $ sudo update-alter...

恰东 ⋅ 46分钟前 ⋅ 0

linux 进程地址空间的一步步探究

我们知道,在32位机器上linux操作系统中的进程的地址空间大小是4G,其中0-3G是用户空间,3G-4G是内核空间。其实,这个4G的地址空间是不存在的,也就是我们所说的虚拟内存空间。 那虚拟内存空间...

HelloRookie ⋅ 46分钟前 ⋅ 0

myatis #{}与${}区别及原理

https://blog.csdn.net/wo541075754/article/details/54292751

李道福 ⋅ 49分钟前 ⋅ 0

三分钟学会如何在函数计算中使用 puppeteer

摘要: 使用 puppeteer 结合函数计算,可以快速的构建弹性的服务完成各种功能,包括:生成网页截图或者 PDF、高级爬虫,可以爬取大量异步渲染内容的网页、模拟键盘输入、表单自动提交、登录网...

猫耳m ⋅ 50分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部