0%

JVM

本文概述

Java虚拟机JVM总结

参考:

Understanding Java Memory Model

JVM

基本概念

JVM为Java虚拟机,包括一套字节码指令集,一组寄存器,一个栈,一个垃圾回收,堆和一个存储方法域。JVM运行在操作系统之上的,他与硬件没有直接的交互

  • java代码的执行
    • 代码编译为class -> javac
    • 装载class -> ClassLoader
    • 执行class
      • 解释执行
      • 编译执行: client compiler/ server compiler
  • 内存管理
    • 内存空间
      • 方法区
      • 方法栈
      • 本地方法栈
      • pc寄存器
    • 内存分配
      • 堆上分配
      • TLAB分配
      • 栈上分配
    • 内存回收
      • 算法(Copy / Mark-Sweep / Mark-Compact)
      • Sun JDK
        • 分代回收
          • 新生代可用的GC(串行copying,并行回收copying,并行copying)
          • Minor GC触发机制以及日志格式
          • 旧生代可用的GC(串行Mark-Sweep-Compact,并行Compacting,并发Mark-Sweep)
          • Full GC触发机制以及日志格式
        • GC参数
        • G1
    • 内存状况分析(jconsole, visualvm,jstat,jmap,MAT)
  • 线程资源同步和交互机制
    • 线程资源同步
      • 线程资源执行机制
      • 线程资源同步机制(Synchronized, lock/ unlock)
    • 线程交互机制
      • wait, notify, notifyAll, double check pattern
      • 并发包提供的交互机制(semaphore,CountwnLatch)
    • 线程状态及分析方法(jstack,TDA)

运行过程

java源文件 –> 编译器 –> 字节码文件

字节码文件 –> JVM –> 机器码、

当一个程序从开始运行,这时虚拟机开始实例化,多个程序启动就存在多个虚拟机实例,程序退出或者关闭,则虚拟机实例小王,多个虚拟机实例之间数据不能共享。

JVM允许一个应用并发执行多个线程。Hotspot JVM中的Java线程与原生操作系统线程有直接的映射关系。当本地存储,缓冲区分配,同步对象,栈,程序计数器等准备好以后,就会创建一个操作系统原生线程。Java线程结束,原生线程随之被回收 。操作系统负责调度所有的线程,并把他们分配到任何可用的CPU上,当原生线程初始化完毕,就会调用Java线程的run()方法,当线程结束时,会释放原生线程和Java的所有资源。

JVM Memory Model

运行资源密集型Java程序时,您必须使用一下某些JVM内存配置

  • XmsSetting – 初始堆大小
  • XmxSetting – 最大堆大小
  • XX: NewSizeSetting – 新一代堆大熊啊
  • XX:MaxNewSizeSetting —最大新一代堆大小
  • XX:MaxPermGenSetting —永久生成的最大大小
  • XX:SurvivorRatioSetting-新的堆大小比率(例如,如果Young Gen大小为10m并且内存开关为–XX:SurvivorRatio = 2,则将为Eden空间保留5m,为两个Survivor空间分别保留2.5m,默认值= 8)
  • XX:NewRatio —提供新旧大小的比率(默认值= 2)

堆内存

  • 堆内存分为年轻一代和老一代
  • JVM启动时分配堆
  • 应用程序运行时堆大小增加或减少
  • 最大大小: -Xms

年轻一代

  • 保留用于包含新分配的对象
  • Young Gen包括三个部分-Eden Memory 和两个Survivor Memory空间(S0,S1)
  • 大多数新创建的对象进入Eden Memory
  • 当Eden Memory 空间中充满对象时,将执行MinorGC(又称Young Collection),并将所有幸存对象移动到其中一个幸存者空间。
  • Minor GC还检查survivor 对象并将其移至其他survivor 空间。因此,其中一个survivor空间经常是空的。
  • 在许多次GC循环后,仍然存在的对象将移至旧代存储空间。通常,可以通过设置年轻一代对象的年龄阈值,然后再有资格晋升为老一代

老一代

  • 这是为了包含可能在多次循环在GC中存货下来长寿命的对象而保留的
  • 当旧一代空间已满时,将执行Major GC(又称Old Collection),需要的时间更长

非堆内存

  • 包括永久生成
  • Perm Gen存储每个类的结构,例如运行时常量池,字段和方法数据,以及方法和构造函数的代码,内部字符串
  • 可以使用-XX: PermSize和-XX: MaxPermSize更改其大小

缓存

  • 代码缓存
  • 存储由JIT编译器生成的已编译代码,JVM内部结构,已加载的探查气代理代码和数据等。
  • 当代码缓存超过阈值时,他将被刷新,并且GC不会从新定位对象。

Stack VS Heap

Java Stack内存用于执行线程,它包含方法特定的值以及对Heap中其他对象的引用:

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Person {
int pid;
String name;
// constructor, setters/getters
}
public class Driver {
public static void main(String[] args) {
int id = 23;
String pName = "Jon";
Person p = null;
p = new Person(id, pName);
}
}

新版Java引入以下新的内存空间

  • Keep Area- Young Generation中的新存储空间,用于包含最近分配的对象,直到下一代Young才执行GC。该区域可防止仅由于在开始young collection之前就已经分配对象
  • Metaspace:Metaspace替代Permanent Generation。即使Perm Gen始终具有固定大小,它也可以自动增加其大小从而达到基础操作系统所提供的大小。只要classloader 处于活跃装填,Metadata保持活跃且无法释放。
-------------本文结束感谢您的阅读-------------

本文标题:JVM

文章作者:Jungle

发布时间:2020年05月30日 - 15:38

最后更新:2020年05月30日 - 15:37

原始链接:http://yoursite.com/2020/05/30/jvm/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Welcome to my other publishing channels