JVM简介

JVM(C#)

1.JVM的位置

jvm运行于操作系统(运行于硬件)上

2.JVM的体系结构

3.类加载器

作用:加载Class文件

  • 虚拟机自带的加载器
  • 启动类(根)加载器
  • 扩展类加载器
  • 应用程序加载器

4.双亲委派机制

java 复制代码
package java.lang;
public class string{
//双亲委派机制:安全//1.APP-->EXC---B00T(最终执行)B00TT1
// EXC// APP
	public string tostring(){
		return "Hello";
	}
	public static void main(string[] args){
		String s=new string();
		System.out.println(s.getclass().getclassLoader());
		s.tostring();
	}
}

5.沙箱安全机制

Java安全模型的核心就是Java沙箱(sandbox),什么是沙箱?沙箱是一个限制程序运行的环境。沙箱机制就是将 Java 代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。沙箱主要限制系统资源访问 ,那系统资源包括什么?------CPU、内存、文件系统、网络。不同级别的沙箱对这些资源访问的限制也可以不一样。

6.Native【重】

java 复制代码
package com.jvm;

public class demo {
    public static void main(String[] args) {
        new Thread(()->{
        },"name").start();
    }
//    凡是带了native的,说明Java的作用范围达不到,回去调用底层C语言的库
//    会进入本地方法栈
//    调用本地方法本地接口  JNI
    
//    JNI的作用:扩展Java的使用,融合不同编程语言为Java所用,最初C、C++
//    java诞生时,C和C++横行,想立足则需调用C、C++中的程序
    
//    他在内存区域中专门开辟了一块区域:Native Method Stack,登记 native 方法
//    在最终执行的时候,加载本地方法库中的方法 通过JNI

//    Java 程序驱动打印机,管理系统,掌提即可,在企业级应用中较为少见!
    private native void start0();
}

7.PC寄存器

程序计数器:Program Counter Register

每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向像一条指令的地址,也即将要执行的指令代码),在执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不计

8.方法区【重】

Method Area方法区

方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法,如构造函数,接口代码也在此定义,简单说,所有定义的方法的信息都保存在该区域,此区域属于共享区间

**【重】**静态方法、常量、类信息(构造方法、接口定义)、运行时的常量池 存在方法区中(static、final、Class、常量池),但是实例变量存在堆内存中,和方法区无关

java 复制代码
public class Test{
	private int a;
	private string name ="qinjiang";
    
	public static void main(string[] args){
    	Test test1 = new Test();
    	test1.a = 1;
        //name若未赋值,则到常量池取值,若赋值,则在堆中处理
    	test1.name ="qinjiag";
}

9.栈

  • 栈:数据结构

  • 栈:先进后出

  • 队列:先进先出(FIFO:First Input First Output)

  • 栈:栈内存,主管程序的运行,生命周期和线程同步;

  • 线程结束,栈内存也就释放,对于栈来说,不纯在垃圾回收

  • 一旦线程结束,栈就Over~

  • 栈:8大基本类型+对象引用+实例的方法

  • 栈+堆+方法区 :交互关系

  • 栈溢出:

  • 栈运行原理:栈帧【test()和main()的放大】

10.三种JVM

  • Sun公司 HotSpot java Hotspot™64-Bit server vM (build 25.181-b13, mixed mode)
  • BEA JRockit
  • IBM J9 VM

11.堆

Heap,一个JVM只有一个堆内存,堆内存的大小是可以调节的。

类加载器读取了类文件后,一般会把什么东西放在堆中?类、方法、常量、变量

引用类型的真实对象;

堆内存中细分三个区域:

  • 新生区(伊甸园区)Yang/New
  • 老生区 Old
  • 永久区 Perm

GC垃圾回收,主要是在伊甸园区和养老区

假设内存满了,OOM,堆内存不够!java.lang.OutOfMemoryError:Java heap space

在JDK8以后,永久存储区改了个名字(元空间);

12.新生区

  • 诞生和成长的地方,甚至死亡;
  • 伊甸园区:所有对象都是在 伊甸园区 new出来的!
  • 幸存区(0、1)

13.老年区

99%的对象都是临时对象

14.永久区

这个区域常驻内存的,用来存放JDK自身携带的Class对象。Interface云数据,存储的是Java运行时的一些环境或类信息,这个区域不存在垃圾回收!关闭VM虚拟机就会释放这个区域的内存

一个启动类,加载了大量的第三方jar包。tomcat部署了太多应用,大量动态生成的放射类,不断的被加载,直到内存满,就会出现OOM

  • jdk1.6之前 :永久代,常量池是在方法区
  • jdk1.7:永久代,慢慢退化了,去永久化,常量池在堆中
  • jdk1.8之后:无永久代,常量池在元空间

元空间:逻辑上存在,物理上不存在

java 复制代码
package com.jvm;

public class demo02 {
    public static void main(String[] args) {
//        虚拟机试图使用最大内存
        long max = Runtime.getRuntime().maxMemory();
//        JVM初始化总内存
        long total = Runtime.getRuntime().totalMemory();
        System.out.println(max+"字节"+max/1024/1024+"MB");
        System.out.println(total+"字节"+total/1024/1024+"MB");
//        默认持况下: 分配的总内存 是电脑内存的 1/4,而初始化的内存:1/64
//-Xms8m -Xmx8m -XX:+PrintGCDetails
        //00M:java.lang.OutOfMemoryError:Java heap
        //尝试扩大堆内存看结果
        // 分析内存,看一下那个地方出现了问题(专业工具)
    }
}

15.堆内存调优

使用JProfile工具

bash 复制代码
-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError

16.GC垃圾回收

JVM在进行GC时,并非对这三个区域统一回收,大部分时候,回收都是新生代~

  • 新生代
  • 幸存区(from to)
  • 老年区

GC两种类:轻GC(普通的GC),重GC(全局GC)

题目:

  • JVM的内存模型和分区~详细到每一个区放什么?

  • 堆里面的分区有哪些?

    • Eden,from,to,老年区,说说他们的特点
  • GC的算法有哪些?

    • 标记清除法,标记整理(压缩)法,复制算法,引用计数法...特点,原理
  • 轻GC和重GC分别在什么时候发生?

    • 轻:伊甸园区
    • 重:伊甸园区、幸存区、老年区

17.GC常用算法

  • 引用计数法
  • 复制算法

好处:没有内存碎片

缺点:浪费了内存空间,多一半空间永远是空的幸存区to

复制算法最佳使用场景:对象存活度较低的时候:新生区~

  • 标记清除算法

先标记清除几次

优点:不需要额外的空间!

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

  • 标记清除压缩算法

再压缩

18.总结

内存效率:复制算法 > 标记清除算法 > 标记压缩算法(时间复杂度)

内存整齐度:复制算法 = 标记压缩算法 > 标记清除算法

内存利用率:标记压缩算法 = 标记清除算法 > 复制算法

难道没有最优算法吗?

没有!没有最好的算法,只有最合适的算法----->GC:分代收集算法

年轻代:

  • 存活率低
  • 复制算法

老年代:

  • 区域大:存活率高

  • 标记清除(内存碎片不是太多) + 标记压缩混合 实现

,会产生内存碎片

  • 标记清除压缩算法

再压缩

外链图片转存中...(img-yjC3xSDT-1710770651457)

18.总结

内存效率:复制算法 > 标记清除算法 > 标记压缩算法(时间复杂度)

内存整齐度:复制算法 = 标记压缩算法 > 标记清除算法

内存利用率:标记压缩算法 = 标记清除算法 > 复制算法

难道没有最优算法吗?

没有!没有最好的算法,只有最合适的算法----->GC:分代收集算法

年轻代:

  • 存活率低
  • 复制算法

老年代:

  • 区域大:存活率高

  • 标记清除(内存碎片不是太多) + 标记压缩混合 实现

相关推荐
Javatutouhouduan1 小时前
Java程序员如何深入学习JVM底层原理?
java·jvm·java面试·后端开发·java架构师·java程序员·互联网大厂
m0_475064501 小时前
jvm中程序计数器
jvm
ANYOLY1 小时前
JVM 线上调优与排查指南
jvm·测试工具
默默coding的程序猿7 小时前
1.单例模式有哪几种常见的实现方式?
java·开发语言·spring boot·spring·单例模式·设计模式·idea
ANYOLY7 小时前
JVM 类加载机制深度解析
jvm
安逸sgr7 小时前
SpringMVC启动流程
java·jvm·spring·spring cloud·eclipse·tomcat·maven
修行者Java1 天前
JVM 内存结构
jvm
那我掉的头发算什么1 天前
【数据结构】优先级队列(堆)
java·开发语言·数据结构·链表·idea
代码程序猿RIP1 天前
【SQLite 库】sqlite3_open_v2
jvm·oracle·sqlite
云灬沙1 天前
IDEA2025无法更新使用Terminal控制台
java·intellij-idea·idea·intellij idea