Java的堆,栈,方法区

关于java内存区域部分的堆,栈,方法区三个部分而言,我总结了一下大概为一下这张图。
这里写图片描述

栈(Stack):

1.为什么栈要用来存储基本变量信息和对象引用

java虚拟机的基本架构就是采用栈来进行设计的。当一个程序需要运行的时候,由于要预先内存空间和运行的生命周期,所以需要进行指针的变动,来进行内存大小的分配。是的,由于这个操作会对程序的执行带来一定的不方便,所以一般栈被用来存放一些基本的变量类型或者引用对象的地址,而对于存储数据量较为庞大的java对象责备存储在了堆里面了。

2.为什么说栈的提取速度比堆要快?

我对于硬件部分也不是很理解,所以这里也只好从软件方面来分析,总结分析之后得出原因有以下几个:
1.栈里面的内存大小一般都是程序启动的时候由系统分配好的。
2.堆的内存大小需要在使用的时候才回去申请,而且每次对于内存大小的申请和归还都会比较消耗性能,开销较大。
3.cpu里面会有专门的寄存器来操作栈,堆里面都是使用间接寻址的方式来进行对象查找的,所以栈会快一些。

3.堆(heap)

1.堆里面存放的内容主要还是new出来的对象和一些数组信息。

2.java的虚拟机不需要知道从堆内存里面存放多少空间大小的变量信息,也不需要知道每个对象的生命周期,所以一般程序运作的灵活性很高。

3.堆区里面存放了大量的对象很信息,所以也成为了gc重点回收的一个区域模块,所以当大量内存被占用的时候,gc的垃圾回收就会成为整个系统的性能瓶颈。于是随着jdk的不断更新,新的技术也对于jvm的内存分配这一块进行一定的优化改善,实现了off-heap。

4.静态方法区:

关于这个概念也可以称之为静态区,静态区和堆很相似,里面存放的信息也是线程共享的,它包含的信息如下图所示:
在这里插入图片描述
方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。

方法区又被称为静态区,是程序中永远唯一的元素存储区域。和堆一样,是各个线程共享的内存区域。它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

Java虚拟机规范对方法区的限制非常宽松,除了和Java堆一样 不需要连续的内存和可以选择固定大小或者可扩展之外,还可以选择不实现垃圾回收。
这区域的内存回收目标主要是针对常量池的回收和类型的卸载,一般而言,这个区域的内存回收比较难以令人满意,尤其是类型的回收,条件相当苛刻,但是这部分区域的内存回收确实是必要的。

很多开发者更愿意把方法区称为“永久代”(Perm Gen)(Permanent Generation)「总是存放不会轻易改变的内容」。在目前已经发布的JDK 1.7 的HotSpot中,已经把原本放在永久代的字符串常量池移至堆中。

运行时常量池(Runtime Constant Pool)是方法区的一部分。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值