JVM相关知识点整理以及性能调优初步理解

  1. JVM 即Java虚拟机 Java跨平台是运行时跨平台 即JRE C/C++是编译时跨平台 。
  2. JVM底层构成 :类加载子系统;JVM运行时数据区(重点);执行引擎。
  3. 类加载子系统:从系统内存中加载类的class文件。
  4. JVM运行时数据区构成:
  • 线程私有数据 每个线程都有自己独立的空间,随线程生命周期而创建和销毁
  • 虚拟机栈每个线程都在这个空间有一个私有的空间。线程栈由多个栈帧组成。一个线程会执行一个或多个方法,每个方法对应一个栈帧1。栈的内存默认最大为1M,超出则会抛出StackOverflowError;
  • 本地方法栈为执行Native本地方法而准备的
  • 程序计数器记录当前线程执行字节码的位置,存储的是字节码指令地址,如果执行的是native关键字修饰的方法,那它的值为空;每个线程都在这个空间有一个私有的空间;CPU在同一时间,只会执行一条线程中的指令。JVM多线程会轮流切换并分配CPU执行时间的方式。为了线程切换后能正常执行,需要通过程序计数器来恢复正确的执行位置。
  • 线程共享数据 所有线程都能访问这块内存数据,随虚拟机或GC而创建和销毁
    • 方法区(元空间) JVM用来存储加载的类的信息、常量、静态变量、编译后的代码等数据
    • 堆内存 JVM启动时创建,存放对象实例。垃圾回收主要就是管理堆内存。堆内存如果满了,就会出现OutOfMemoryError 内存溢出
    • 新生代
    • 老年代
      线程私有数据(栈、本地方法栈、程序计数器(指向当前线程所执行的字节码指令的地址行号))
      线程共享数据(堆、方法区(元空间))。

当一个程序开始执行后会在栈、本地方法栈、程序计数器中各分配一个空间;在同一个线程中不同的方法会在该线程中创建不同的栈帧,而这些栈帧统一放在该线程的栈中(同样按照先进后出的规则);栈帧中又包含了局部变量表、操作数栈、方法出口等其他一些内容。局部变量表中如果有对象类的变量,那它是存放在堆中,对象的模板信息存放在方法区(元空间),同一个对象如果被实例化多次那么堆中就有多个对象而方法区中只有一个模板;由栈帧中的局部变量表指向堆。本地方法栈中处理的是被native(表示方法底层实现是通过C/C++实现的)关键字修饰的方法。

JVM性能调优;为什么要进行性能调优?

Java为什么需要采用分带回收策略 — 目的为了减少full gc的次数

扩展 当JVM内存到达临界点时触发垃圾回收机制。
堆底层的划分: 新生代,老年代,其内存比例为1:2;
新生代其中包含Eden(伊甸园),from,to区域,其内存比例为8 :1:1。
98%的对象在Eden区进行创建(还有对象逃逸,大对象优先进入老年代等)。当Eden区被对象占满之后Java 会触发minor gc;minor gc 根据gc root 判断Eden区的对象是否处于游离状态,如果对象没有引用或被调用的话(游离状态),就会被回收消失,如果对象不处于游离状态则会被存入from区;每次minor gc 后Eden区都会清空,未被回收的对象每经过一次minor gc它的age都会+1。当from区被对象占满后,它同样也会触发minor gc ,此时from区就会变为to区(变为to区后原有对象数据清空),to区就会变为from区;之前from区(现在是to区)中仍然不处于游离状态的对象就会拷贝至to区(现在是from区)同时对象的age+1;到最后当对象的age到达15时候仍然处于非游离状态,那么这个对象(简称为‘老不死’)就会移动至老年代;当老年代被对象占满后会触发另一种回收full gc(压缩老年代内存) ,这种gc很慢它会触发STW(stop the world)会让系统不能提供任何服务。


  1. 注脚的解释 :栈帧由局部变量表、操作数栈、动态链接。方法返回地址、附加信息等组成; ↩︎

你可能感兴趣的:(笔记,java,jvm)