类加载器

类装载器ClassLaoder负责加载class文件,class文件开头有特定的文件标识,将class文件字节码内容加载到内存中,并将这些内容转换成方法区中的运行时数据结构,并且ClassLoader只负责class文件的加载,至于它是否可以运行,则有Execution Engine决定虚拟机自带的类加载器

引导类加载器

这个类加载使用C/C++与亚伯实现的,嵌套在JVM内部,它用来加载Java的核心库(JAVA_HOME/jre/lib/rt.jar、resources.jar或sun.boot.class.path路径下的内容),用于提供JVM自身需要的类

并不继承自java.lang.ClassLoader,没有父加载器

加载扩展类和应用程序类加载器,并指定未他们的父类加载器,处于安全考虑,Bootstrap启动类加载器只加载包名未java、javax、sun等开头的类

扩展类加载器

Java语言编写

派生于ClassLoader类

父类加载器为启动类加载器

从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安装目录的jre/lib/ext,子目录下加载类库。如果用户创建的JAR放在此目录下,也会自动由扩展类加载器加载

应用类加载器

java语言编写

派生于ClassLoader类

父类加载器为扩展类加载器

它负责加载环境变量classpath或系统属性 java.class.path指定路径下的类库,改类加载器是程序默认的类加载器

自定义加载器

一个JVM实例只存在一个堆内存,堆内存的大小是可以调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行。堆逻辑上分为三部分:新生+养老+永久

新生区是类的诞生、成长、消亡的区域,一个类在这里产生,应用,最后被垃圾回收器收集、结束生命。新生区又分为两部分,伊甸区和幸存者区,所有的类都是在伊甸区被new出来的。幸村区有两个:0区和1区。当伊甸区的空间用完时,程序又创建对象,JVM的垃圾回收器将对伊甸区的进行垃圾回收(MinorGC),将伊甸园区中的不再被其他对象所引用的对象进行销毁,然后将将伊甸园区中的剩余对象移动到幸存0区。若幸存0区也满了,再对该区进行垃圾回收,然后移动到1区.那如果1区也满了呢?

再移动到养老区。若养老区也满了,那么这个时候将产生MajorGC(FullGC),进行养老区内存清理。若养老区执行了Full GC之后依然无法进行对象的保存。就会产生OOM异常。

如果出现java.lang.OutofMemoryError:java heap space 异常,说明Java虚拟机的堆内存设置不够。原因有二:

(1)Java虚拟机的堆内存设置不够,可以通过参数-Xms,-Xmx来调整。

(2)代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被引用),在Java8中,永久代已经被移除,被一个称为元空间的区域所取代。元空间的本质和永久代类似

元空间和永久代之间最大的区别在于:

永久代使用的JVM的堆内存,但是Java8以后的元空间并不在虚拟机中而是使用本机物理内存,因此默认情况下,元空间的大小仅受本地内存限制。类的元数据放入native memory,字符串池和类的静态变量放入Java堆中,这样可以加载多少类的元数据就不再由MaxPermSize控制,而由系统的实际可用空间来控制

Java虚拟机栈

栈管运行,堆管存储

栈也叫主内存,主管Java程序的运行,是线程创建时创建,它的生命周期是跟随线程的生命周期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题,只要线程一结束改栈就over,生命周期和线程一致,是线程私有的。8种基本类型的变量+对象的引用变量+实例方法都是在函数的栈内存中分配

栈存储什么?

栈帧主要保存三类数据:

本地变量:输入参数和输出参数以及方法内的变量(8中基本数据类型,对象的引用地址),部分结果并参与方法的调用和返回

栈操作:记录出栈、入栈的操作

栈帧数据:包括类文件、方法等等。

栈运行原理:

每个方法执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息,每一个方法从调用直至执行完毕的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。栈的大小和具体JVM的实现有关,通常在256k~756K之间

,约等于1Mb左右,不存在垃圾回收问题

本地方法栈

方法区

供各线程共享的运行时内存区域。它存储了每一个类的结构信息,例如运行时的常量池、字段、和方法数据、构造函数和普通方法的字节码内容。上面讲的是规范,在不同的虚拟机里头实现是不一样的,最典型的就是永久代和元空间。

寄存器

记录了方法之间的调用和执行情况,类似排班值日表,用来存储指向下一条指令的地址,也即将要执行的指令代码,它是当前线程所执行的字节码的行号指示器每个线程都有一个程序计数器,是线程私有的,就是一个指针,指到方法区中的方法字节码(用来存储指向下一条指令的地址,也即将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记这块内存区域很小,它是当前线程所执行的字节码的行号指示器,字节码解释器通过改变这个计数器的值来选取下一条需要执行的字节码指令如果执行的是一个Native方法,那这个计数器是空的,用以完成分支、循环、跳转、异常处理、线程恢复等基础功能。不会发生内存溢出(OOM) 错误。

双亲委派机制的好处:

防止类被重复加载

保护程序安全,防止核心API被随意篡改

GC四大算法:

引用计数法:

每次对对象赋值时要维护引用计数器,且计数器本身也有一定的消耗较难处理循环引用,JVM的实现一般不采用这种方式

复制算法

年轻代中使用的MinorGC这种GC算法采用的是复制算法(Coping)

HOtSpot把年轻代分为了三部分:1个Eden区和2个Survivor区(分别叫from和to)。默认比例8:1:1,一般情况下新创建的对象都会被分配到Eden区(一些大对象特殊处理),这些对象经过第一次Minor GC后,如果仍然存活,将会被移到Survivor区。对象在Survivor区中每熬过一次Minor GC,年龄就会增加1岁,当他的年龄增加到一定程度时,就会被移动到老年代中。因为年轻代中的对象基本都是朝生夕死(90%),所以在年轻代的垃圾回收算法使用的是复制算法,复制算法的基本思想就是将内存分为两块,每次只用其中一块当这一块内存用完,就将还活着的对象复制到另外一块上面。复制算法不会产生内存碎片。

标记清除

老年代一般是由标记清除或者标记清除与标记整理的混合实现,算法分成标记和清除两个阶段,先标记要回收的对象,然后统一回收这些对象,用通俗的话解释一下标记清除算法,就是当程序运行期间,若可以使用的内存被耗尽的时候,GC线程就会触发并将程序暂停,随后将要回收的对象标记一遍,最终统一回收这些对象,完成标记清理工作接下来便让应用程序恢复运行

优点:不需要额外空间

缺点:两次扫描耗时严重,会产生内存碎片

标记压缩:

标记/整理算法唯一的缺点就是效率也不高,不仅要标记所有存活对象,还要整理所有存或对象的引用地址。从效率上来说,标记/整理算法要低于复制算法,没有最好的收集算法,只有最合适的收集算法分代收集算法

年轻代的特点是区域相对老年代较小,存活率低这种情况复制算法的回收整理速度是最快的。老年代的特点是区域大,对象存活率高,这种情况复制算法明显变得不合适。一般是由标记清除或标记整理的混合实现

java写值日表_Java知识之JVM相关推荐

  1. java 是用什么写的_java里的jvm是用什么语言写的

    JAVA里的jvm虚拟机用的是C语言+汇编语言开发的.在此之上就是JAVA本身了,虚拟机是起到解析作用. 另外,JAVA并不比C语言慢,说JAVA慢一般是九十年代那时候的JAVA. 现在一段优秀的JA ...

  2. java开发流程图_Java 详解 JVM 工作原理和流程

    作为一名Java使用者,掌握JVM的体系结构也是必须的. 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言.Java类文件格式.Java ...

  3. java 指定垃g1圾收集_Java知识梳理--JVM

    众所周知Java是的蓬勃兴起有一部分原因是因为Java的跨平台行,和优秀的内存管理,z这些都赖于其虚拟机的支持,所以虚拟机成为Java学习者跨步不去的坎.下图是对虚拟机整体的概述,可以使我们大体了解虚 ...

  4. java写值日表_jvm - z_先生 - 博客园

    jvm jvm的理解 虚拟机有什么更新 什么是OOM stackOverflowError 有哪些方法分析 jvm常用的调优参数 jvm类加载器的认识 jvm的体系结构概述 Object o = ne ...

  5. java内存 海子_Java虚拟机:JVM内存模型和volatile详解

    JVM内存模型和volatile详解 Java内存模型 随着计算机的CPU的飞速发展,CPU的运算能力已经远远超出了从主内存(运行内存)中读取的数据的能力,为了解决这个问题,CPU厂商设计出了CPU内 ...

  6. java 串讲_Java知识串讲

    一.JDK个版本之间的区别: 1.JDK1.5的新特性: 泛型ArrayList list = new ArrayList();-->ArrayList list = new ArrayList ...

  7. java jstack使用_JAVA语言之JVM 中jstack命令使用详解

    本文主要向大家介绍了JAVA语言之JVM 中jstack命令使用详解,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. Java程序问题定位时线程栈信息是一个重要线索,如下: " ...

  8. java jsr命令_Java系列:JVM指令详解(下)(zz)

    九.自增减指令 该指令用于对本地(局部)变量进行自增减操作.该指令第一参数为本地变量的编号,第二个参数为自增减的数量. 比如对于代码: int d=10; d++; d+=2; d--; 其指令为: ...

  9. java写花束_Java作业 题目:16版.情人节送玫瑰花

    1.实验要求 本实验要求:以情人节送花为业务背景,体验自定义异常以及异常处理机制. 1-1. 业务说明: 1-1.1. 本实验以情人节送花为业务背景,女方提出送花需求,男方送出鲜花. 1-1.2. 当 ...

最新文章

  1. android 从零单排 第一期 按键显示helloworld
  2. 无盘机服务器,无盘服务器操作系统
  3. java consul服务发现_分布式项目(七)consul 服务注册与发现
  4. Leetcode 5
  5. Spring+SpringMVC+MyBatis深入学习及搭建(十二)——SpringMVC入门程序(一)
  6. WPF 使用 Font Awesome(OTF / TTF)
  7. JavaCV的摄像头实战之七:推流(带声音)
  8. 联通专线切换成移动专线问题故障解决
  9. 牛腩——SQLhelper
  10. 【K站神器】百度SEO尊诺发包程序
  11. 帝国cms 自定义页面 php,帝国CMS增加自定义页面模板修改教程
  12. 我入门的小程序,居然已经用户过万(上)
  13. vue2.0桌面端框架_Element-UI组件库(Vue2.0桌面端组件库)V2.9.2 免费版
  14. 华为鸿蒙系统基于安卓系统方面有哪些提升
  15. 对接应用宝SDK(YSDK)QQ能登录微信无法登陆的一些解决方法**
  16. 案例:程序员离职在家,全职接单心得
  17. Linux 的目录树
  18. PCIE/GPU/显卡参数性能查看工具搜集
  19. android 2.3 wifi (二)
  20. 微位移:一种高效的硬件图像压缩算法

热门文章

  1. 漫谈linux文件io,Linux文件IO与通用块层的请求合并
  2. babel原理_【JavaScript】深入理解Babel原理及其使用
  3. 两小时课程值2000?清晖PMP最后两小时冲刺点题你参加了吗?
  4. Makefile执行报错:make: *** No rule to make target ` ‘, needed by xxx. Stop.
  5. easyUI 中datagrid 上下左右移动编辑器
  6. ssh输入正确的密码不能登录报错:pam_tally2(sshd:auth):/var/log/tallylog is either world writable or not normal
  7. 如何判断树莓派GPIO引脚是否损坏
  8. 【DevOps】持续集成的流程及jenkins的介绍
  9. Spark开发语言Scala语言
  10. Java编码规范_ali规范