JVM——JVM中内存划分

JVM是干啥的

用一个韦恩图表示
在这里插入图片描述

JVM出现的初心是为了实现跨平台,一次开发到处运行。JVM屏蔽了系统和硬件上的差异。
JVM就相当于一个“翻译”,针对不同的外来软件硬件机器都可以“翻译”成本地特有的语言。
运行在Windows上的JVM和运行在Linux上的JVM不是同一个程序

现在来看,JVM存在的意义已经不仅仅是为了跨平台了,而是提供了一个"生态圈"
JVM能够屏蔽系统的差异,发明一些新的语言,想跨平台,就可以直接借助JVM来完成,只要让这个语言编译生成的是和JVM匹配的字节码,此时就可以直接借助JVM来运行你的语言,同时也能保证Java中现成的海量的第三方库,也能同时使用。

包含部分
1、类加载
在 JVM 启动时或者类运行时将需要的 class 加载到 JVM 中
2、执行引擎
执行引擎的任务是负责执行 class 文件中包含的字节码指令,相当于实际机器上的 CPU
3、动态内存管理器
将内存划分成若干个区以模拟实际机器上的存储、记录和调度功能模块,如实际机器上的各种功能的寄存器或者 PC 指针的记录器等
4、本地方法调用
调用 C 或 C++ 实现的本地方法的代码返回结果

JVM中的内存区域划分

JVM启动之后就会从操作系统申请一大块内存, 再针对这个内存划分出一些区域.
JVM申请了一大块内存后,也会把这个内存分成若干区域.不同的区域分别用来做不同的事情.
一个java进程中,可能包含着多个线程,多个线程之间,共用同一份堆和方法区,但是每个线程有自己的栈和程序计数器

每个进程有自己的堆,多个进程之间不共享!

在这里插入图片描述

决定某个变量是在栈上还是堆上,和这个变量是基础类型还是引用类型无关,和这个变量是局部变量还是成员变量或者是静态变量有关。

public class Test {
    //t2是成员变量,t2这个引用就是在堆上
    Test t2 = new Test();

    public static void main(String[] args) {
        //t是局部变量,t这个引用就是在栈上
        Test t = new Test();
    }
}

1、堆(运行时常量池)
new的对象就放到堆中
2、方法区
加载好的类,还有静态成员
3、栈(JVM栈/本地方法栈)
局部变量
4、程序计数器
存放的是地址,描述当前线程接下来要执行的指令在内存的哪个地方。

堆溢出

Java堆用于存储对象实例,只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免来GC清除这些对象,那么在对象数量达到最大堆容量后就会产生内存溢出异常。

运行程序的时候,给java加上一些选项,就可以控制内存区域的大小(堆的大小)
在这里插入图片描述
配置JVM运行时的内存区域的大小.
构造堆溢出,循环创建对象,把对象加到List集合类里. (防止被GC回收)
java.lang.OutOfMemoryError

栈溢出

构造栈溢出,递归方法,无限递归
Stackc OverflowError

猜你喜欢

转载自blog.csdn.net/char_m/article/details/107615145