内存栈

所谓的内部栈,是为了与数据结构的栈相区分开来。

今天所说的栈是指虚拟机内存里的栈。

什么是栈呢?它是java虚拟机里的内存组成部分。

从内存角度来讲,当我们创建了一个对象,那么它就会被分配到内存中,那么当我们要对这个对象进行操纵时,该怎么办呢。

我们需要把这个对象从内存中“取”出来,如何取呢?

如果现在有三个线程需要操作这个对象,那么我们需要从内存中read出这个对象的内容,创建对象副本,分别放到三个栈中,在栈中直接操作对象的副本,而不再与内存发生关系,当操作完对象副本后,又会把得到的结果write回内存。

这其中的过程可以用一副图来说明:

(拷贝)

这是因为java的内存是以栈帧为单位的。每个线程就代表一个栈,每个方法代表一个线程,那么每个方法都会在栈中产生一个帧,这些帧各自包含一组局部变量,这组局部变量就是这个方法在执行过程中所需的所有变量。

栈是有大小的。1.6之后的栈大小是1MB(不太准确,有待考证)。

每个栈都会以一种内部机制赋予一定的大小,当栈只进行压栈,而不出栈的话,就容易出现栈溢出异常:StackOverflowException。

当然在从内存中取对象的时候也涉及到安全问题,准确的说是考虑到读的同步性,三个线程同时对对象进行操作,一定会有先后顺序问题。

这里有两种解决方法,一种是ThreadLocal方式,它的实现方式是把对象从内存中抽离,不妨咋内存中,这样一来栈与内存的read过程就不存在了。同步问题得到解决(这里有疑问)。

第二种方式是volatile。这种方式其实也不绝对是安全的。对于volatile修饰的变量,jvm虚拟机只是保证从主内存加载到线程工作内存的值是最新的,但是如果加载之后内存中的值发生变化,那么volatitle就没有办法了,因为它并不能保证原子性。

所以说方法执行是在栈中进行的,对数据不停地进行压栈和出栈,以此进行数据的运算。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值