java内存区域

在学习jvm之前,觉得有必要先了解一下虚拟机是个什么操作。虚拟机有很多种,有常用的vmvare,我想学习linux指令,最好安装一个linux系统,但是我又不想安装双系统,怎么办,那就在vmvare中安装linux,仿佛多了一台计算机。
c,c++编译好的程序,换到另一台计算机上运行,可能会出错,而java程序,一次编译,到处运行,这是因为jvm的无比威力。

所以什么是虚拟机?

虚拟机是通过软件模拟物理机中所拥有的硬件系统功能,并且在隔离的环境中运行。

jvm?

c,c++程序是在物理机上直接编译运行,使用的是物理机的指令集,数据的表达形式等,因为每台计算机可能其数据形式不同,指令集不同,编写好的程序在特定的计算机可以运行,换到其他计算机上就运行不了。
但是java程序它是在jvm上进行编译运行,相当于在物理机和java程序之间加了一层软件,jvm能够支持不同的操作系统,不同的物理机,只要你的计算机下载了jdk。所以,java程序能够做到一次编写,到处运行,代价就是其速度不如c,c++。
jvm封装了很多底层细节,比如内存分配,垃圾回收,这些都由jvm代替程序员完成。


进入正题,因为jvm为我们提供了内存分配,相信好奇的java程序员还是会想知道底层到底是怎么实现的,更重要的是在出现内存溢出、泄露时能帮助我们定位问题。

运行时数据区
这里写图片描述
与其他语言不同,jvm在执行java程序过程中将内存划分为若干个不同的数据区域。在java程序中涉及到的数据有类信息,实例对象,静态变量,常量,实例变量,局部变量,对这些数据的创建时间,生命周期是不一样的。比如堆区是需要经常回收的区域,将实例对象存放于这一区域,方法区相当于永久代,不会轻易被回收的区域,将类信息,即时编译信息等放置此区。虚拟机栈、本地方法栈、程序计数器都是线程私有的。

如果不划分区域,完全放置一个区里会怎么样?
更复杂的垃圾回收算法,更复杂的内存分配算法,艰难的内存创建,对象定位等等

下面对每个区做一个详细的描述:

1.程序计数器

存放的是当前线程正在执行的指令地址
存在原因:确定指令执行位置,在多线程抢占到cpu资源,在控制语句返回后能定位到正确的执行位置。
说明:

  • 线程私有
  • 记录当前指令执行地址
  • 如果执行的是native方法,程序计数器为undefined
  • 是内存区域中唯一一个不会出现OutofMemoryError的区域

2.方法区

存放的是类元信息,静态变量(static),常量(final),即时编译器编译后的代码。
在jdk1.7以后就将字符串常量池移到堆区中。
说明:线程共享

3.堆区

在虚拟机启动时就创建,存放的对象实例,几乎所有的对象实例都在堆上分配,还有一部分会在栈上分配。这是垃圾回收器的主要回收区域,由于现在的垃圾回收器是基于分代收集算法,所以堆区被分为eden,survivor1,survivor2,tenured。
java堆可以是物理上不连续的,只要是逻辑上连续的即可。

4.虚拟机栈

线程私有,方法调用时都会创建一个栈帧存放到栈中,方法调用结束后,从栈中弹出栈帧。栈帧中存放的主要有局部变量表,操作数栈,动态链接,出口等信息。

局部变量表:存放编译期已知的基本数据类型,对象引用类型,returnAddress。每个条目长度为32位,如果是64位的long,double类型基本数据,就占据俩个局部变量空间。

public void test(int a,int b){
    int c = 0;
    c = a + b;
    Object o = new Object();
}

0 reference this
1 int int a
2 int int b
3 int int c
4 reference o

操作数栈:java方法中所有的参数传递都是通过操作数栈进行的,在java中没有寄存器

public static int add(int a,int b){
    int c = 0;
    c = a + b;
    return c;
}

0:iconst_0 //0压栈
1:istore_2 //弹出int,存放于局部变量2中,2指的是c,0指的是a,1是b
2:iload_0 //把局部变量0压栈
3:iload_1 //把局部变量1压栈
4:iadd //弹出俩个变量,求和,结果压栈
5:istore_2 //弹出结果,放于局部变量2
6:iload_2 //局部变量2压栈
7:return //返回

这里写图片描述

5.本地方法栈

与虚拟机栈类似,只不过本地方法栈服务的为本地方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值