JVM内存模型
2024-01-09 17:26:39 0 举报
JVM内存模型是Java虚拟机的定义,用于描述Java程序在运行时如何分配和管理内存。它主要包括以下几个部分: 1. 堆内存(Heap):用于存储对象和数组的内存区域。堆内存是线程共享的,因此需要垃圾收集器来管理内存。 2. 非堆内存(Non-Heap):用于存储不属于堆内存的其他数据,如静态变量、常量等。非堆内存包括方法区、JVM内部处理等。 3. 方法区(Method Area):用于存储已被加载的类信息、常量、静态变量等。方法区是线程共享的,需要垃圾收集器来管理内存。 4. 程序计数器(Program Counter Register):用于存储当前线程所执行的字节码的行号指示器。程序计数器是线程私有的,不会发生内存溢出。 5. 栈内存(Stack):用于存储局部变量、方法参数等。栈内存是线程私有的,它的生命周期与线程相同。 6. 本地方法栈(Native Method Stack):用于存储本地方法的信息。本地方法栈是线程私有的,它的生命周期与线程相同。 JVM内存模型通过合理的内存分配和垃圾收集,使得Java程序能够高效、安全地运行。
作者其他创作
大纲/内容
该区域是线程共享的,很少发生垃圾回收使用直接内存
线程栈1-Xss
动态链接
线程栈2-Xss
(native方法)本地方法区
每个线程栈都有自己的程序计数器和本地方法
存储方法中定义的局部变量
记录指令行号
from(1/10)
本地方法
局部变量
执行引擎
运行时数据区
堆(对象)
新生代-Xmn
记录方法在main方法的位置:方法执行结束的方法出口
1/3
新生代和老年代的比例为1:2老年代永久对象装满发生:Full GC1、full gc 发生时:stop the word2、full gc未能释放空间:OOMGC:标记复制算法(CMS)/分区收集算法(G1/ZGC)
打破双亲委派机制:用自定义的类加载可以实现打破双亲委派机制;通过继承ClassLoader类,重新findClass和loadClass方法实现;在loadClass方法中不直接调用findClass方法,而不在根据parent.loadClass方法去找父类ClassLoader;这样就直接通过findClass方法找到自己定义的AppClassLoader。
栈帧(main方法)
程序计数器
年轻代(Eden区/from区/to区):当数据从from区移到to区往复15次,就会直接进入老年代大对象直接进入老年代/长期存活对象进入老年代/老年代担保机制GC:复制算法(ParNew)
用于标记代码当前执行到哪一行
年轻代:当Eden区装满,发生minor gc,回收年轻代,将不能回收的数据存入survivor from区,survivor-to区移入from区,from区和to区倒转;当一个对象被minor gc 15次数,直接被放入老年代
本地方法库(其他语言编写的方法库)
线程栈
Eden(8/10)
栈
引导类加载器/扩展类加载器/应用类加载器/自定义加载器双亲委派机制:先找父亲加载,再由儿子自己加载;沙箱安全机制/避免类重复加载
用于计算方法中定义的局部变量计算
堆-Xms-Xmx
方法区(元空间)常量/静态变量/类信息
LoadClass类加载过程:加载->验证->准备->解析->初始化->使用->卸载加载java.class文件
类加载器
栈帧2
字符串常量池
栈是运行时创建的,是线程私有的,生命周期于线程相同,存储声明的变量
其他语言主要是C++/C,如:Hotspot
线程栈(main线程)
方法出口
操作数栈
运行时常量池
栈帧3
堆
本地方法接口(其他语言编写的接口暴漏给java调用)
from->to minor Gc15次
to(1/10)
即时编译器JIT
老年代(2/3)
minor GC:1、引用计数法(互循环引用的问题)2、可达分析算法(GC Roots:线程栈的本地变量、静态变量、本地方法栈的变量)
输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果
每个线程栈都可以有一个或者多个栈帧,栈帧是一个先进后出队列(FILO),即方法调用顺序:先被调用的最后执行结束,后被调用的先执行结束。
堆:虚拟机启动时创建1、堆中存放的对象可以被线程栈->栈帧->局部变量->对象引用2、元空间定义的对象->指针引用到堆
方法区(元空间)-XX:MetaspaceSize-XX:MaxMetaspaceSize
将符号引用转化为直接引用(每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有该引用是为了支持方法调用过程中的动态连接)
字节码解析器
垃圾收集
栈帧1
0 条评论
下一页