JVM,JDK,JRE定义

  • JVM是Java Virtual Machine(Java虚拟机)的缩写。
  • JDK是Java Development Kit JAVA语言开发工具箱(JAVA核心)
  • JRE是Java Runtime Environment 运行环境

  以上三者的关系是这样的

  

  • JDK除了包含JRE以外的,还包含了由把JAVA编译为CLASS的工具,还有监控JVM运行状态的工具jconsole,jcmd,jmat等等
  • JRE包含了运行JAVA的类库等
  • JVM

  JVM特点原理(WRITE ONCE RUN EVERY WHERE)

  • JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。(平台需要安装系统对应的JDK版本)
  • JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令(01010101010)执行。Java语言的一个非常重要的特点就是与平台的无关性。
  • JVM作用和过程,编译器把JAVA源代码编译为类文件,然后通过类加载器把CLASS文件加载进去内存空间,内存空间(方法区,JAVA堆,栈)使用垃圾回收机制来管理内存空间

  为什么需要学习JVM

  • JAVA语言与C等语言不同在于JAVA中对内存管理封装在JVM内部,因此我们要掌握内存管理。才能在程序出现问题时候快速定位,解决问题。
  • 关于内存管理需要学习JAVA运行时数据区,以及JMM内存模型

  运行时数据区

  

  程序计数器:

  • 指向当前线程正在执行的字节码指令的地址 行号 (保护线程记忆)当某一线程被挂起后,线程本身是不知道自己做了什么,挂起恢复后该做什么,因此需要程序来计数器来恢复没做完任务的代码,然后继续完成没做完的任务。当CPU在轮流执行线程的时候,返回原先线程所需要的记录。

  

  虚拟机栈:

  • 存储当前线程运行方法时所需要的数据,指令,返回地址。一个线程对应一个虚拟机栈,一个方法对应一个栈贞,每个栈帧的大小主要由局部变量表的字段决定的栈的大小可以设置Xss来设置,其中一个栈默认大小是1M,栈不能无限生产,一般在3-5K个,栈的大小设置如果太小,面对有方法循环嵌套和递归的方法,栈的大小是不足以存储运行方法所需的数据指令,会发生栈溢出,此时会发生栈扩展,如果栈扩展失败就会造成内存溢出。如果栈的大小设置太大,则会减少可支持的线程数量,面对多线程的环境会造成内存溢出。局部变量表存基本数据类型值,以及引用类型纸箱堆的地址。

  

  本地方法栈:

  • 基本是同虚拟机栈功能结构类似,但是该栈是针对本地方法,也就是说他的栈帧存的方式是本地方法,本地方法是指用NATIVE关键字修饰的方法,实现一般是C++实现的

  方法区:

  • 存储类信息,常量final修饰(1.7以后不包括String常量池),静态变量,JIT(动态代理生产的类信息)

  

  堆:

  • 它是JVM用来存储对象实例,可以认为Java中所有通过new创建的对象的内存都在此分配,Heap中的对象的内存需要等待GC进行回收。于属性而言,若果是基本数据类型则存放对象和值如果是其他引用类型则存放对象和该对象指向方法区的引用,与方法而言,存放该方法在方法区的地址。

  

  堆中还细分为这种结构(年轻代(1E+2S)年老代和持久代),1.8以后JDK除去了持久代,使用META SPACE来代替,相对于垃圾回收机制而然

  

  年轻代:

  • 所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。年轻代分三个区。一个Eden区,两个 Survivor区(一般而言)。大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个 Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制“年老区(Tenured)”。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。而且,Survivor区总有一个是空的。同时,根据程序需要,Survivor区是可以配置为多个的(多于两个),这样可以增加对象在年轻代中的存在时间,减少被放到年老代的可能。可用Xmn设置大小,比例一般是8:1:1,年轻代的大小一般是整个堆大小的30-50%,官方推荐3/8

  年老代:

  • 在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。

  持久代:

  • 用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate 等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=<N>进行设置。

  JVM内存结构

 

  JVM垃圾回收

GC (Garbage Collection)的基本原理:将内存中不再被使用的对象进行回收,GC中用于回收的方法称为收集器,由于GC需要消耗一些资源和时间,Java在对对象的生命周期特征进行分析后,按照新生代、旧生代的方式来对对象进行收集,以尽可能的缩短GC对应用造成的暂停

Minor GC

一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。

Full GC

对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个对进行回收,所以比Scavenge GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。有如下原因可能导致Full GC:

  • 年老代(Tenured)被写满
  • 持久代(Perm)被写满
  • System.gc()被显示调用
  • 上一次GC之后Heap的各域分配策略动态变化

一纸理解JVM的更多相关文章

  1. 深入理解JVM内幕(转)

    转自:http://blog.csdn.net/zhoudaxia/article/details/26454421/ 每个Java开发者都知道Java字节码是执行在JRE((Java Runtime ...

  2. 深入理解JVM内幕:从基本结构到Java 7新特性

    转自:http://www.importnew.com/1486.html 每个Java开发者都知道Java字节码是执行在JRE((Java Runtime Environment Java运行时环境 ...

  3. [译]深入理解JVM

    深入理解JVM 原文链接:http://www.cubrid.org/blog/dev-platform/understanding-jvm-internals 每个使用Java的开发者都知道Java ...

  4. 深入理解JVM垃圾收集机制(JDK1.8)

    垃圾收集算法 标记-清除算法 最基础的收集算法是"标记-清除"(Mark-Sweep)算法,分两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象. 不足: ...

  5. 深入理解JVM(一)编译openJDK

    此文总结的很不错:https://www.cnblogs.com/ACFLOOD/p/5528035.html 准备openJDK源码和环境 1.在linux和macOS上编译openJDK更加友好, ...

  6. 走进JVM【二】理解JVM内存区域

    引言 对于C++程序员,内存分配与回收的处理一直是令人头疼的问题.Java由于自身的自动内存管理机制,使得管理内存变得非常轻松,不容易出现内存泄漏,溢出的问题. 不容易不代表不会出现问题,一旦内存泄漏 ...

  7. 《深入理解JVM虚拟机》读书笔记

    前言:<深入理解JVM虚拟机>是JAVA的经典著作之一,因为内容更偏向底层,所以之前一直没有好好的阅读过.最近因为刚好有空,又有了新目标.所以打算和<构架师的12项修炼>一起看 ...

  8. 理解JVM GC

    理解JVM GC对于我们把控Java应用有很大的帮助.下面我从运维角度,把网上的JVM相关的资料整理如下,以加深对JVM GC的理解.如有错误的地方,请看官指正. JVM内存使用分类 JVM的内存分区 ...

  9. 如何从编程的本质理解JVM内存模型

    如何从编程的本质理解JVM内存模型 一般聊JVM内存模型都是把图截出来,然后对着图,解释上面堆.栈之类的概念.这篇将分享下,如何从编程的本质上理解,JVM内存模型是什么样子,为什么是这个样子,不再死记 ...

随机推荐

  1. 期末Java Web大作业----简易的学生管理系统

    学生信息管理系统(大作业) 2018-12-21:此文章已在我的网站更新,添加视图介绍等信息,源码请移步下载https://www.jeson.xin/javaweb-sims.html PS:首先不 ...

  2. 1064 Financial Management

    http://acm.hdu.edu.cn/showproblem.php?pid=1064 思路:看懂英文就很简单,就是12个数相加求平均数就ok了. 扩展: C++ 标准输入输出流的控制符 #in ...

  3. 上传插件webupload之调用拍照兼容问题

    在项目中,移动端用到了webupload插件来实现上传功能(我觉得这个插件挺好用的,所以无论pc还是移动端我都使用了这个插件来做上传功能) 在移动端要调起拍照功能,实现上传,须得在webuploade ...

  4. vs2012开发基于MFC的ActiveX控件

    1.新建工程 2.一直点击下一步,直到出现一下界面,注意红色标注选项,点击完成. 3.进入工程的属性界面,设置工程属性 4.添加对话框资源及其他控件,添加对话框类, 5.设置对话框属性 6.设置Dia ...

  5. 一步一步 copy163: 网易严选 ---- vue-cli

    面试点 组件间通信 生命周期函数 路由 - 参数 - 重定向 vuex 参考 网易严选商城小程序全栈开发,域名备案中近期上线(mpvue+koa2+mysql) 小程序服务端源码地址 小程序源码地址 ...

  6. c++编译错误C2971:"std::array":array_size:包含非静态存储不能用作废类型参数;参见“std::array”的声明

    在Qt5中这段代码编写有两种方式:一个编译成功,一个失败 成功版本: static constexpr size_t block_size = 0x2000;//8KB static constexp ...

  7. javascript 编程风格 部分精要

    1 换行保持两个缩进(通常是一行太长) 运算符前后加一个空格,包括赋值运算符和逻辑运算符 括号运算符,左括号之后,右括号之前不应该有空格 段代码无关,添加空行 命名驼峰式,一般首字母小写,其他单词首字 ...

  8. Oracle 存储过程 PROCEDURE

    存储过程  一组用于完成特定数据库功能的SQL语句集,该SQL语句集经过编译后存储在数据库系统中.在使用时候,用户通过指定已经定义的存储过程名字并给出相应的存储过程参数来调用并执行它,从而完成一个或一 ...

  9. 开启IIS Express可以调试X64项目

    //来源:https://blog.csdn.net/ma_jiang/article/details/52679431 现在项目开发时总有时需要在X64下开发,这样我们就需要IIS Express中 ...

  10. 深入理解JVM(七)——性能监控工具

    前言 工欲善其事必先利其器,性能优化和故障排查在我们大都数人眼里是件比较棘手的事情,一是需要具备一定的原理知识作为基础,二是需要掌握排查问题和解决问题的流程.方法.本文就将介绍利用性能监控工具,帮助开 ...