JVM

作者: OPice | 来源:发表于2019-12-12 14:25 被阅读0次

什么是JVM

   JVM是java virtual mechine 的缩写,是在真实的计算机基础上模拟计算机的各种功能的一种实现,JVM的本身对于计算机而言也是一个程序。
   Java的跨平台性其实是依赖JVM,也就是在任何计算机平台安装JVM,就可以执行java的字节码文件,达到了"一处编译,处处运行"。

JVM的组成部分

JVM由五部分组成:堆、栈:(虚拟机栈、本地方法栈)、方法区、程序计数器。


image.png

:根据对象的声明周期不同,划分不一样的区域:新生代、老年代、永久代(1.8之后被元空间取代)。新生代存放的一些朝生夕死的对象,老年代存放一些大对象或者多次GC后还存在的对象,永久代存放一些类信息、常量、静态变量等数据。这样划分的目的,是为了更好的回收内存,对于一些需要频繁回收,声明周期短的对象,放在新生代中。

image.png
其中Eden区和From Survivor区、To Survivor区比例8:1:1,GC开始时对象只会存在Eden和From区,To区是空的。GC进行时,Eden区存活的对象会被复制到To区,From区会根据对象的年龄来决定去向,默认15,超过会将From区移到老年代,否则移到To 区。 接着会将Eden和From 区清空,然后将To 区域的对象重新复制到新的From区域。其中如果To区没有足够的空间来保存上次新生代存活下的对象时,有老年代担保将这些对象放在老年代中。

虚拟机栈:是用于描述java方法执行的内存模型。每个方法在执行的时候都会创建一个栈帧,栈帧的组成:局部变量表、操作数栈、动态连接、方法出口。每个方法执行的过程就是一个压栈和出栈的过程。

image.png

每个线程有独自的虚拟机栈,线程之间隔离。若单个线程请求栈的深度大于虚拟机允许的深度,会抛出StackOverFlowError。

本地方法栈 :本地方法栈于虚拟机栈类似,不同的是调用的native方法。

方法区:类的信息、常量、静态变量等信息,1.7开始,字符串常量池移到java heap中,1.8 开始元空间取代永久代。方法区只是一种规范,一开始HotSpot只是用永久代来实现方法区,能够省去这块内存回收的逻辑。但是永久代受-XX:MaxPermize大小限制,会出现OOM。

程序计数器:较小的一块空间,主要是记录程序执行字节码的行号指示器。对于Java的多线程而言,是通过切换分配处理器执行时间来实现的,所以为了线程切换后能够恢复到正确的位置,每条线程都有一个程序计数器。

垃圾收集器和内存分配策略

  对于Java来说,程序计数器、虚拟机栈、本地方法栈这些是伴随着线程一块销毁,而堆和方法区是需要回收的,针对这块内存JVM如何分配,如何收入,下面就来一块看下。

  首先,先搞明白这三个问题:

  • 哪些内存需要回收?
  • 什么时候回收?
  • 如何回收
  1. 哪些内存需要回收?
      堆和方法区,最主要的就是堆,每次GC就会回收堆里70%-80%左右内存。堆里主要存放的就是对象和常量池,所以先要判断哪些对象和方法区是可以回收的。
    判断对象已死的方式:
  • 引用计数法
    如果对象被引用+1,引用失效-1,当值为0时对象可回收,这种方式的缺陷在于如果两个对象互相引用,比如: a=b; b=a; a=null; b=null; 这时对象引用不为0,事实上a,b两个对象都可以回收的。
  • 可达性算法分析
    以“GC Root” 为起点,往下如果引用链中没有该对象,则回收该对象,即使被finalize的对象,也是有可能逃离回收的命运,真正的回收是需要经过两次标记,当第一次finalize的时候,会将对象发在F-Queue队列中,会对队列再次执行finalize这时对象如果被引用就会逃离被回收的命运。


    image.png

GC Root的对象:虚拟机栈的局部变量表的所有对象;方法区静态属性的所有对象;方法区常量的所有对象;Native方法的所有对象。

  • 引用类型:强、弱、软、虚
    只是用做标记对象的状态,强引用:抛出OOM也不会回收 ;弱引用:在抛出OOM之前会尝试回收弱引用的对用,多用于图片和网站缓存;软引用:存活在下次GC之前;虚引用:没有实际应用场景,随时可以被回收。
  1. 什么时候回收?
      对象在被标记不可达对象时,也不会立即被回收,回收的动作是发生在对象分配空间不足时,才会真正的执行回收动作。

  2. 如何回收?
      针对不同代回收的机制不同,新生代都是朝生夕死的对象使用的是复制算法,将Eden区和From区没有被回收的区域复制到To区,然后将Eden和From清空,在将To区的对象复制到From区。
      老年代的回收方式,对于一些大对象考虑内存的问题,适用标记清除和标记整理。

工具和相关参数配置

java自带的命令

  • jps 列出虚拟机进程
  • jstat 虚拟机监视信息统计工具
  • jmap java某个进程所有对象的信息
  • jstack java堆栈跟踪工具
    图形化工具 jconsole

参数配置

打印trace信息

参数 描述
-XX:+PrintGC或者-verbose:gc 打印GC日志
-XX:+PrintGCDetails GC详细日志
-XX:+PrintGCTimeStamps gc的时间戳
-Xloggc:/log/gc.log gc文件的目录
-XX:+PrintHeapAtGC 打印GC前后堆的日志
-XX:TraceClassLoading 监控类的加载

堆的分配参数
堆的内存= 年轻代+老年代+永久代
永久代固定值64m,年轻代建议占3/8。

参数 描述
-Xmx,-Xms 堆的最大值和最小值,开发过程中经常配置为一样的,是为了GC后不需要重新分配造成资源浪费

-XX:+HeapDumpOnOutOfMemoryError、-XX:+HeapDumpPath
查看系统dump的时候发生什么,导出OOM的路径。

相关文章

  • 深入JVM内核 目录

    深入JVM内核 目录 深入JVM内核1 初识JVM深入JVM内核2 JVM运行机制深入JVM内核3 常用JVM配置...

  • JVM内存模型(jvm 入门篇)

    概述 jvm 入门篇,想要学习jvm,必须先得了解JVM内存模型,JVM内存模型,JVM内存模型,JVM内存模型,...

  • Jvm(一)-Java虚拟机的内存管理

    [toc] JVM JVM回顾 1. 什么是 JVM JVM是Java Virtual Machine(Java虚...

  • JVM介绍系列文章

    知晓JVM系列(一):对JVM总览知晓JVM系列(二):JVM内存管理机制与优化初探知晓JVM系列(三) :常用的...

  • 科普

    1.JVM/JRE/JDK关系JVM

  • JVM

    JVM之内存模型JVM之对象定位与访问JVM之Java垃圾回收机制JVM之类加载

  • JVM

    栈容量由-Xss指定深入理解JVM—JVM内存模型 JVM内存模型和JVM参数的关系

  • JVM基础知识系列

    JVM基础系列 JVM知识点扫盲系列(1) JVM知识点扫盲系列(2) JVM内存的那些事 JVM类加载的那些事 ...

  • (过时、作废)android 多线程 — GC

    简单解析下JVM 先说下 JVM,虽然上篇文章在讲内存时介绍了 JVM ,但是我在这里还是以 JVM 开头,JVM...

  • 技术文章罗列

    JVM JVM知识点详解JVM初步诊断JVM内存模型 Java Api java8 stream Api讲解(上)...

网友评论

      本文标题:JVM

      本文链接:https://www.haomeiwen.com/subject/rpzngctx.html