堆内存和栈内存区别以及jvm存放数据剖析

本文详细介绍了Java中的栈和堆内存,栈主要存储基本类型、对象句柄和局部变量,其存取速度快但大小和生存期受限。堆内存用于动态分配对象,由垃圾回收器管理,提供更大的灵活性但速度较慢。优化建议包括使用基础类型、预估集合大小以减少扩容开销。此外,还讨论了堆和栈溢出的情况以及指针与地址的区别。
摘要由CSDN通过智能技术生成

栈是按线程分配的,堆是共享的

1. 栈(stack)

  在Java中,栈(stack)是由编译器自动分配和释放的一块内存区域,主要用于存放一些基本类型(如int、float等)的变量、指令代码、常量及对象句柄(也就是对象的引用地址)。

  栈内存实际上就是满足先进后出的性质的数学或数据结构,栈内存的操作方式类似于数据结构中的栈(仅在表尾进行插入或删除操作的线性表)。

  栈的优势在于,它的存取速度比较快,仅次于寄存器,栈中的数据还可以共享,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间。

  缺点表现在,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

2.堆(heap)

  堆(heap)是一个程序运行动态分配的内存区域,堆内存实际上指的就是优先队列的一种数据结构.

  在Java中,构建对象时所需要的内存从堆中分配。这些对象通过new指令“显式”建立,这种分配方式类似于数据结构中的链表。

  堆内存在使用完毕后,是由垃圾回收(Garbage Collection,GC)器“隐式”回收的。

  堆的优势是在于动态地分配内存大小,可以“按需分配”,其生存期也不必事先告诉编译器,在使用完毕后,Java的垃圾收集器会自动收走这些不再使用的内存块。

  缺点为,由于要在运动时才动态分配内存,相比于栈内存,它的存取速度较慢。

总结: 

  1.Java开发时候尽量使用基础类型,少使用包装类型

  2.定义集合的时候尽量指定大小,减少扩容开销

堆内存对应jvm的堆,存储成员(静态)变量和声明时(静态)字符串变量的值内存;栈内存对应jvm的栈,存储局部变量和局部方法(也称栈帧)以及它们的引用和值内存:

static a()在堆内存中,因为他是

当栈中的元素需要被外部类引用时,栈会分配指针地址给堆内存指针使用(指针地址占用栈内存空间,也就是说引用都在栈中)(指针在运行时可以改变其所指向的值,而引用一旦和某个对象绑定后就不再改变,总是指向最初的对象)也就是常说的:

  • 堆溢出:不断的new 一个对象,一直创建新的对象,
  • 栈溢出:死循环或者是递归太深,递归的原因,可能太大,也可能没有终止。

另外jvm的元空间是存放运行时静态字符串变量,运行时class类的信息

指针与地址的区别:
  1、指针和地址最大的区别就是指针是有类型的,地址是没有类型的。我们当然可以通过绝对地址的方式找到函数和数据,但是地址是没有类型的,不能对地址进行算术操作,在涉及诸如数组等操作时就不能通过地址的自增和自减来访问数组的各个变量。
  2、指针是由地址和类型两部分构成的,指向数据的指针不仅记录该数据的在内存中的存放的地址,还记录该数据的类型,即在内存中占用几个字节,这是地址所不具有的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

swordbob

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值