JVM————虚拟机的内存分配

一、堆

在虚拟机初始化时创建,初始化对象和成员变量,所有的对象数组都要在堆上分配

关于堆的分代

堆通常可分为新生代和老年代,新生代包括1个Eden和两个Survivor区,Survivor区又包括from区和to区。

minnor GC from区中的数据会和to区进行复制算法,交换数据,当次数满15次会发生full GC将数据移动到老年区
为什么最大age是15?
因为对象的年龄存放在对象中,占4bit最多表示16个数,年龄为0-15

分代的原因是为了减少STW的次数提高系统的吞吐量

 

二、方法区

jdk1.8之后为元空间,存放常量,静态变量,类元信息(类的组成信息)

方法区内还有运行时常量池

用于存放静态编译产生字面量符号引用
常量池具有动态性,也就是说常量并不一定是编译时确定,运行时生成的常量也会存在这个常量池中。

三、栈

 1、虚拟机栈(栈内存)

虚拟机栈是由栈帧组成

栈帧有四部分组成

(1)局部变量表

    a=1;
    a=2;

基本数据类型、returnAddress类型(指向一条字节码指令的地址)和对象引用,这个对象引用有可能是指向对象起始地址的一个指针,也有可能是代表对象的句柄或者与对象相关联的位置。局部变量所需的内存空间在编译器间确定。

(2)操作数栈

用来存储运算结果以及运算的操作数,它不同于局部变量表通过索引来访问,而是压栈和出栈的方式

(3)动态链接

Math math = new Math();
math.compute();
程序在运行过程中,通过Math对象的对象头,对象头指向方法区的类元信息动态链接就是符号引用在程序运行过程中根据对象的头指针找到这个方法所对应的入口的内存地址,把这个地址存放到动态链接中将符号引用在程序运行过程中转变为直接引用

(4)方法出口

    return的值

 2、本地方法栈

native()
启动一个线程start方法的源码里面会调用start0()方法,它就是一个native方法,然后再通过C语言或者C++实现找.dll文件去实现C语言本地方法的局部变量就存放在jvm的本地方法栈中

四、程序计数器

每个程序计数器都是不同的线程,表示执行当前线程的字节码指令(地址)的行号

该内存区域是唯一一个java虚拟机规范没有规定任何OOM情况的区域。


常量池在哪?

Java6和6之前,常量池是存放在方法区中的。

Java7,将常量池是存放到了堆中,常量池就相当于是在永久代中,所以永久代存放在堆中。

Java8之后,取消了整个永久代区域,取而代之的是元空间。没有再对常量池进行调整。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值