精华内容
下载资源
问答
  • 局部变量表

    2017-03-31 15:30:00
    由于局部变量表在栈帧之中,因此,如果函数的参数和局部变量较多,会使得局部变量表膨胀,从而每一次函数调用就会占用更多的栈空间,最终导致函数的嵌套调用次数减少。 import com.sun.org.ap...

    局部变量表示栈帧的重要组成部分之一。

     
    它用于 保存函数的参数以及局部变量
     
    局部变量表中的变量只在当前函数调用中有效,当函数调用结束后,随着函数栈帧的销毁,随之销毁。
     
    由于局部变量表在栈帧之中,因此,如果函数的参数和局部变量较多,会使得局部变量表膨胀,从而每一次函数调用就会占用更多的栈空间,最终导致函数的嵌套调用次数减少。
    import com.sun.org.apache.regexp.internal.RE;

    /**
    * Created by wb-xxd249566 on 2017/3/31.
    */
    public class TestStackDeep {
    private static int count=0;

    public static void recursion(long a,long b,long c){
    long e=1,f=2,g=3,h=4,i=5,j=6,k=7,l=8,m=9,n=10;
    count++;
    recursion(a,b,c);
    }

    public static void recursion(){
    count++;
    recursion();
    }
    public static void main(String[] args){
    try {
    // recursion();
    recursion(0l,0l,0l);
    }catch (Throwable e){
    System.out.println("deep of calling = "+count);
    // e.printStackTrace();
    }
    }
    }
    俩次执行的结果:
     
    可以看到,在相同的栈容量下,局部变量少的函数可以支持更深的函数调用。
     
    使用jclasslib工具可以更进一步查看函数的局部变量信息。
     


     可以看到,在Class文件的局部变量表中, 显示了每个局部变量的作用域范围、所在槽位的索引(index列)、变量名(name列)和数据类型(J表示long型)。
    栈帧中的局部变量表中的槽位是可以重用的,如果一个局部变量过了其作用域,那么在其作用域之后申明的新的局部变量就很有可能会服用过期局部变量的槽位,从而达到节省资源的目的。
    import com.sun.org.apache.regexp.internal.RE;

    /**
    * Created by wb-xxd249566 on 2017/3/31.
    */
    public class IndexReuse {

    public void localvar1(){
    int a = 0;
    System.out.println(a);
    int b = 0;
    }
    public void localvar2(){
    {
    int a = 0;
    System.out.println(a);
    }
    int b = 0;
    }
    }
    在localvar1()函数中,局部变量a和b都作用到了函数末尾,故b无法复用a的位置。
    在localvar2()函数中,局部变量a在作用域外不再有效,故局部变量b可以复用a的槽位(1个字)
     
     
     
      局部变量表中的变量也是重要的垃圾回收根节点,只要被局部变量表中直接或间接引用的对象都是不会被回收的。
    通过示例展示局部变量对垃圾回收的影响:
    /**
    * Created by wb-xxd249566 on 2017/3/31.
    */
    public class LocalVarTabGc {

    public void localvarGc1(){
    byte[] a = new byte[6*1024*1024];
    System.gc();
    }

    public void localvarGc2(){
    byte[] a = new byte[6*1024*1024];
    a = null;
    System.gc();
    }

    public void localvarGc3(){
    {
    byte[] a = new byte[6*1024*1024];
    }
    System.gc();
    }

    public void localvarGc4(){
    {
    byte[] a = new byte[6*1024*1024];
    }
    int c = 10;
    System.gc();
    }

    public void localvarGc5(){
    localvarGc1();
    System.gc();
    }

    public static void main(String[] args){
    LocalVarTabGc ins = new LocalVarTabGc();
    ins.localvarGc5();
    }
    }
    在上述代码中,每一个localvarGcN()函数都分配了一块6MB的堆空间,并使用局部变量表引用这块空间。
    localvarGc1() 中,在申请空间后,立即进行垃圾回收,由于byte数组被变量a引用,因此无法回收这块空间:

     localvarGc2()中,在申请空间后,将变量a置为null,使byte数组失去强引用,故垃圾回收可以顺利回收byte数组:
    localvarGc3()中,在申请空间后,虽然使局部变量a失效,a已经离开了作用域,但是变量a依然存在于局部变量表中,并且也指向这块byte数组,故依然无法回收:

     localvarGc4()中,在垃圾回收之前,不仅使变量a失效,离开了作用域,更是申明了变量c,使c复用了a的字,由于a此时已被销毁,故可以回收byte数组:
     
    localvarGc5(),第一次GC后byte数组所存在的局部变量表已经被销毁,byte数组失去引用,因此第二GC时被回收:
     

    转载于:https://www.cnblogs.com/xxdfly/p/6651610.html

    展开全文
  • JVM--局部变量表

    千次阅读 2018-01-08 12:40:24
    java局部变量表是栈帧重要组中部分之一。他主要保存函数的参数以及局部的变量信息。局部变量表中的变量作用域是当前调用的函数。函数调用结束后,随着函数栈帧的销毁。局部变量表也会随之销毁,释放空间。 由于...

    java局部变量表是栈帧重要组中部分之一。他主要保存函数的参数以及局部的变量信息。局部变量表中的变量作用域是当前调用的函数。函数调用结束后,随着函数栈帧的销毁。局部变量表也会随之销毁,释放空间。

    由于局部变量表存在栈帧中。所以,如果函数参数和局部变量比较多,会使的局部变量表膨胀,每一次调用会占用更多的栈空间。最终结局就是栈空间内存一定的情况下调用的次数减少。

    1.1.1. 局部变量表变量影响

    下面的代码演示在栈空间内存一定的情况下,参数以及局部变量的大小对函数调用次数的影响。第一个函数recursion()不包含任何的参数和局部变量,第二个函数recursion()包含3个参数和4个局部变量,因此我们也可以算出局部变量表中包含了13个变量信息。第一个局部变量表拥有更深的调用层次。代码如下:

    1. private static int count=0;  
    2. public static void recursion(int a,int b,int c){  
    3. long l1=12;  
    4. short sl=1;  
    5. byte b1=1;  
    6. String s="1";  
    7. System.out.println("count="+count);  
    8. count++;  
    9. recursion(1,2,3);  
    10. }  
    11. public static void recursion(){  
    12. System.out.println("count="+count);  
    13. count++;  
    14. recursion();  
    15. }  
    private static int count=0;
    public static void recursion(int a,int b,int c){
    long l1=12;
    short sl=1;
    byte b1=1;
    String s="1";
    System.out.println("count="+count);
    count++;
    recursion(1,2,3);
    }
    public static void recursion(){
    System.out.println("count="+count);
    count++;
    recursion();
    }


    使用jvm参数-Xss128K执行上面第一个无参的recursion()函数,输出结果如下:

    1. count=4495  
    2. Exception in thread "main" java.lang.StackOverflowError  
    3. at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)  
    count=4495
    Exception in thread "main" java.lang.StackOverflowError
    at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)


    使用jvm参数-Xss128K执行上面第二个个有参的recursion()函数,输出结果如下:

    1. count=3865  
    2. Exception in thread "main" java.lang.StackOverflowError  
    3. at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)  
    4. at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:564)  
    5. at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:619)  
    count=3865
    Exception in thread "main" java.lang.StackOverflowError
    at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)
    at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:564)
    at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:619)


    可以得出结论:

    在同等的栈容量下,局部变量少的函数可以支持更深的函数调用。调用次数也就越多。

    如何证明结论是正确的呢?在这里我们借助jclasslib工具来查看局部变量表的局部变量信息。

    下图显示了无参的recursion()函数最大的局部变量表大小为0个字。有参的recursion()函数最大的局部变量表大小为8个字。在这里说明一下:

    int、short、byte、对象引用等占用一个字。long和double在局部变量中需要占用2个字。

    (字 一个字在32位计算机中为4个字节的长度)

    我们来算一下recursion(1,2,3);方法局部变量表的大小。

    三个参数为int 所以 是3

    long l1=12; 2

    short sl=1; 1

    byte b1=1; 1

    String s="1"; 1

    所以说 一共是8个字。

    需要强调的一点是这里说的局部变量表指的是java栈空间的一部分,不要跟下面说的classs字节码中的局部变量表混淆。

     

    下面展示class字节码中的局部变量表的内容:

     

     

    从图中看以看出来一些信息:

    在Class文件的局部变量表定义中,显示了每一个局部变量的作用范围、所在槽位的索引信息(index列信息),

    变量的名称(name列)和数据类型信息(descriptor列)

    数据类型信息映射:

    I---int类型

    D--double类型

    B-byte类型

    Ljava/lange/Integer --Integer类型

    Ljava/lange/String--String类型

    S--short类型

    栈帧中的局部变量的槽位是可以重复使用的。如果一个声明的变量过了其作用域,那么其作用域之后申请的变量有可能复用过期的局部变量的槽位,从而能够达到节省资源目的。

    1.1.2. 局部变量表槽位的复用

    下面得代码显示了局部变量表槽位的复用。localVar1()函数中,局部变量a和b得范围都是到了函数的末尾所以b是没有办法复用a的卡槽所在的位置。localVar2()函数中,局部变量a在}之后不在有效了,所以b是可以复用a的卡槽的位置都是int类型所以是1个字。程序如下所示:

    public void localVar1(){

    int a=0;

    System.out.println(a);

    int b=0;

    }

    public void localVar2(){

    {

    int a=0;

    System.out.println(a);

    }

    int b=0;

    }

    使用jclasslib工具来查看局部变量表的局部变量localVar1()信息如下图:

     


     

     

    该函数最大的局部变量大小3个字,卡槽0位为thsi引用(实例方法的第一个局部变量都是this),第一个卡槽位变量为a,第二个卡槽位变量为b,每个变量是1个字所以一共是三个字。

    使用jclasslib工具来查看局部变量表的局部变量localVar2()信息如下图:

     


     

    该函数最大的局部变量大小2个字,卡槽0位为thsi引用(实例方法的第一个局部变量都是this),第一个卡槽位变量为a,第二个卡槽位变量为b,每个变量是1个字 但是b变量复用了a卡槽位所以一共是2个字。

     

    局部变量表也是作为垃圾回收gc的重要参考点,只要被局部变量表中直接或者间接引用的对象都不会被回收。所以必须要理解局部变量表才能理解gc回收机制。

    下面的主要讲解说明局部变量对垃圾回收的影响。

    1.1.3. 局部变量对垃圾回收的影响

    程序代码如下所示:

    jvm参数-XX:+PrintGC参数 垃圾回收前后堆得大小

    JvmTestLocalVarGc t=new JvmTestLocalVarGc();

    t.localvarGc1();

    结果输出:[Full GC 3875K->3546K(15872K), 0.0050719 secs]

    在申请空间后,立即调用GC垃圾回收,很明显,由于byte被b强引用所以无法回收这块空间。

    JvmTestLocalVarGc t=new JvmTestLocalVarGc();

    t.localvarGc2();

    结果输出:[Full GC 3875K->474K(15872K), 0.0036066 secs]

    在垃圾回收前,现将b设置为null,使byte数组拾取引用,所以GC后byte数组被直接垃圾回收了。

    JvmTestLocalVarGc t=new JvmTestLocalVarGc();

    t.localvarGc3();

    结果输出:[Full GC 3875K->3546K(15872K), 0.0069622 secs]

    在进行垃圾回收前,先使局部变量b实现,虽然b离开了作用域,但是变量b亦然存放在局部变量表中。并且指向byte数组,故byte数组亦然没有被回收。

    JvmTestLocalVarGc t=new JvmTestLocalVarGc();

    t.localvarGc4();

    结果输出:[Full GC 3875K->474K(15872K), 0.0037666 secs]

    在垃圾回收前,不仅是b失效了,c复用了变量b的字,由于b被销毁,所以byte数组被销毁了。

    JvmTestLocalVarGc t=new JvmTestLocalVarGc();

    t.localvarGc5();

    结果输出:[Full GC 3875K->3546K(15872K), 0.0054367 secs]

    [Full GC 3546K->474K(15936K), 0.0036164 secs]

    对于localvarGc5()调用localvarGc1()方法,很明显localvarGc1()中没有回收byte数组,但在其返回后他的栈帧被销毁了,自然栈帧中所有的局部变量也没销毁了,容器没了,值当然也不存在了嘛。

    所以byte数组失去饮用。在localvarGc5()中被回收了。

              

    展开全文
  • JVM 之(15)局部变量表

    千次阅读 2018-06-09 21:25:45
    《JVM 之(1)运行时数据区》提到,虚拟机栈是描述Java方法执行的内存模型:每个方法执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。本篇主要分析局部变量...
            在《
    JVM 之(1)运行时数据区》提到,虚拟机栈是
    描述Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。本篇主要分析局部变量表的原理结构。

            局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。在Java程序被编译为Class文件时,就在方法的Code属性的max_locals数据项中确定了方法所需要分配的最大局部变量表的容量。

            局部变量表的容量以变量槽(Variable Slot)为最小单位,虚拟机规范中并没有明确指明一个Slot暂用的内存空间大小,只是很有“导向性”地说明每个Slot都应该能存放一个boolean,byte,char,short,int,float,refrence,returnAddress类型的数据,这种描述明确指出 “每个Slot占用32位长度的内存空间” 有一些差别,它允许Slot的长度随着处理器,操作系统或虚拟机的不同而发生变化。不过无论如何,即使在64位虚拟机中使用64位长度的内存空间来实现Slot,虚拟机仍要使用对齐和补白的手段让Slot在外观上看起来和32位虚拟机中得一致。

            既然前面提到了数据类型,在此顺便说一下,一个Slot可以存放一个32位以内的数据类型,Java中用32位以内的数据类型有:boolean,byte,char,short,int,float,reference,returnAddress八种类型。reference是对象的引用。虚拟机规范即没有说明它的长度,也没有明确指出这个引用应由怎样的结构,一般来说,虚拟机实现至少都应当能从此引用中直接或间接的查找到对象在Java堆中得起始地址索引和方法区中得对象类型数据。而returnAddress是为字节码指令jsr,jsr_w 和 ret服务的。它指向了一条字节码指令的地址。

            对于64位的数据类型,虚拟机会以高位在前的方式为其分配两个连续的Slot空间。Java语言中明确规定的64位的数据类型只有long和double数据类型分割存储的做法与"long和double的非原子性协定" 中把一次long 和double 数据类型读写分割为两次32位读写的做法类似,在阅读JAVA内存模型时对比下。不过,由于局部变量表建在线程的堆栈上,是线程私有的数据,无论读写两个连续的Slot是否是原子操作,都不会引起数据安全问题。

            虚拟机通过索引定位的方式使用局部变量表,索引值的范围是从0开始到局部变量表最大的Slot数量。如果32位数据类型的变量,索引N就代表了使用第N个Slot,如果是64位数据类型的变量,则说明要使用第N个和N+1两个Slot。

            在方法执行时,虚拟机是使用局部变量表完成参数值到参数变量列表的传递过程。如果是实例方法(非static的方法),那么局部变量表中第0位索引的Slot默认是用于传递方法所属对象实例的引用,在方法中可以通过关键字this来访问这个隐含的参数,其余参数则按照参数表的顺序来排列,暂用从1开始的局部变量Slot,参数表分配完毕后,在根据方法体内部定义的变量顺序和作用域分配其余的Slot。

            局部变量表中得slot是可重用的,方法体定义的变量,其作用域并不一定会覆盖整个方法体,如果当前字节码PC计数器的值已经超过了某个变量的作用域,那么这个变量对应的Slot就可以交给其他变量使用。这样的设计不仅仅是为了节省栈空间,在某些情况下Slot的复用会直接影响到系统的垃圾收集行为。例如如下代码:

    [java]  view plain  copy
    1. /** 
    2.  * VM args: -verbose:gc 
    3.  *  
    4.  */  
    5. public class GCTest {  
    6.     public static void main(String[] args) {  
    7.         byte[] _64M = new byte[1024 * 1024 * 64];  
    8.         System.gc();  
    9.     }  
    10. }  
    运行结果:

    [GC 66558K->65952K(129024K), 0.0015650 secs]

    [Full GC 65952K->65853K(129024K), 0.0122710 secs]

    从运行结果分析,发现System.gc()运行后并没有回收掉这64M的内存。

    没有回收掉"_64M"的内存能说的过去,因为在执行System.gc()时,变量_64M还处于作用域之内,虚拟机自然不敢回收掉该内存。我们把代码位如下:

    [java]  view plain  copy
    1. /** 
    2.  * VM args: -verbose:gc 
    3.  *  
    4.  */  
    5. public class GCTest {  
    6.     public static void main(String[] args) {  
    7.         {  
    8.             byte[] _64M = new byte[1024 * 1024 * 64];  
    9.         }  
    10.         System.gc();  
    11.     }  
    12. }  
    从代码逻辑上将,在执行System.gc()的时候,变量“_64M”已经不可能在被访问了,但执行以下这段程序,会发现运行结果如下:

    [GC 66558K->65968K(129024K), 0.0014760 secs]

    [Full GC 65968K->65853K(129024K), 0.0127180 secs]

    这是为什么呢?

    在解释为什么之前,我们先对代码进行第二次修改。在调用 System.gc()之前加入代码int x=0,  这个修改看起来莫名其妙,但运行以下程序,却方法这次内存针对被正确回收了。

    [java]  view plain  copy
    1. /** 
    2.  * VM args: -verbose:gc 
    3.  *  
    4.  */  
    5. public class GCTest {  
    6.     public static void main(String[] args) {  
    7.         {  
    8.             byte[] _64M = new byte[1024 * 1024 * 64];  
    9.         }  
    10.         int x=0;  
    11.         System.gc();  
    12.     }  
    13. }  

    [GC 66558K->65936K(129024K), 0.0027120 secs]

    [Full GC 65936K->317K(129024K), 0.0129600 secs]

    局部变量"_64M"能否被回收的根本原因就是:局部变量表中得Slot是否还存有关于_64M数组对象的引用。第一次修改,代码虽然离开了_64的作用域,但在此之后,没有任何对局部变量表的读写操作,_64M 原本所占用的Slot还没有被其他变量所复用,所以作为GC Roots 一部分的局部变量表让然保持对它的关联。这种关联没有被及时打断,在绝大部分情况下都很轻微。但如果遇到一个方法,其后面的代码有一些耗时很长的操作,而前面又占用了大量的内存,实际上已经不会在被使用的变量,手工将其设置为NULL值(用来代替int x=0)把变量对应的局部变量表Slot情况,就不是一个毫无意义的操作,这种操作可以作为 一种在及特殊情形(对象暂用内存大,此方法的栈帧长时间不能被回收,方法调用次数达不到JIT编译条件)下得“奇技” 来使用。但不应当对赋null值操作有过多的依赖,也没有必要把它当做一个普遍的编码方法来推广,以恰当的变量作用域来控制变量回收时间才是最优雅的解决方法。

    另外,赋null值的操作在经过虚拟机JIT编译器优化之后会被消除掉,这时候将变量设置为null实际上是没有意义的。字节码被编译为bending代码后,对GC Roots的枚举也与解释执行时期有所差别,在经过JIT编译后,System.gc()执行时就可以正确的回收掉内存。

    打印GC详细日志还可以加上参数:

    -XX:+PrintGCDetails -XX:+PrintGCTimeStamps



    [java]  view plain  copy
    1. /** 
    2.  * VM args: -verbose:gc 
    3.  *  
    4.  */  
    5. public class GCTest {  
    6.     public static void main(String[] args) {  
    7.         byte[] _64M = new byte[1024 * 1024 * 64];  
    8.         System.gc();  
    9.     }  
    10. }  
    运行结果:

    [GC 66558K->65952K(129024K), 0.0015650 secs]

    [Full GC 65952K->65853K(129024K), 0.0122710 secs]

    从运行结果分析,发现System.gc()运行后并没有回收掉这64M的内存。

    没有回收掉"_64M"的内存能说的过去,因为在执行System.gc()时,变量_64M还处于作用域之内,虚拟机自然不敢回收掉该内存。我们把代码位如下:

    [java]  view plain  copy
    1. /** 
    2.  * VM args: -verbose:gc 
    3.  *  
    4.  */  
    5. public class GCTest {  
    6.     public static void main(String[] args) {  
    7.         {  
    8.             byte[] _64M = new byte[1024 * 1024 * 64];  
    9.         }  
    10.         System.gc();  
    11.     }  
    12. }  
    从代码逻辑上将,在执行System.gc()的时候,变量“_64M”已经不可能在被访问了,但执行以下这段程序,会发现运行结果如下:

    [GC 66558K->65968K(129024K), 0.0014760 secs]

    [Full GC 65968K->65853K(129024K), 0.0127180 secs]

    这是为什么呢?

    在解释为什么之前,我们先对代码进行第二次修改。在调用 System.gc()之前加入代码int x=0,  这个修改看起来莫名其妙,但运行以下程序,却方法这次内存针对被正确回收了。

    [java]  view plain  copy
    1. /** 
    2.  * VM args: -verbose:gc 
    3.  *  
    4.  */  
    5. public class GCTest {  
    6.     public static void main(String[] args) {  
    7.         {  
    8.             byte[] _64M = new byte[1024 * 1024 * 64];  
    9.         }  
    10.         int x=0;  
    11.         System.gc();  
    12.     }  
    13. }  

    [GC 66558K->65936K(129024K), 0.0027120 secs]

    [Full GC 65936K->317K(129024K), 0.0129600 secs]

    局部变量"_64M"能否被回收的根本原因就是:局部变量表中得Slot是否还存有关于_64M数组对象的引用。第一次修改,代码虽然离开了_64的作用域,但在此之后,没有任何对局部变量表的读写操作,_64M 原本所占用的Slot还没有被其他变量所复用,所以作为GC Roots 一部分的局部变量表让然保持对它的关联。这种关联没有被及时打断,在绝大部分情况下都很轻微。但如果遇到一个方法,其后面的代码有一些耗时很长的操作,而前面又占用了大量的内存,实际上已经不会在被使用的变量,手工将其设置为NULL值(用来代替int x=0)把变量对应的局部变量表Slot情况,就不是一个毫无意义的操作,这种操作可以作为 一种在及特殊情形(对象暂用内存大,此方法的栈帧长时间不能被回收,方法调用次数达不到JIT编译条件)下得“奇技” 来使用。但不应当对赋null值操作有过多的依赖,也没有必要把它当做一个普遍的编码方法来推广,以恰当的变量作用域来控制变量回收时间才是最优雅的解决方法。

    另外,赋null值的操作在经过虚拟机JIT编译器优化之后会被消除掉,这时候将变量设置为null实际上是没有意义的。字节码被编译为bending代码后,对GC Roots的枚举也与解释执行时期有所差别,在经过JIT编译后,System.gc()执行时就可以正确的回收掉内存。

    打印GC详细日志还可以加上参数:

    -XX:+PrintGCDetails -XX:+PrintGCTimeStamps



    展开全文
  • 看下图代码例子,double类型的b,占用两个slot,所以index为3和4

     

    看下图代码例子,double类型的b,占用两个slot,所以index为3和4

     

     

     

     

     

    展开全文
  • 局部变量表所需的容量大小是编译期确定下来的,并保存方法的Code属性的maximum local variables数据项中,方法运行期间是不会改变局部变量表的大小的。 方法嵌套调用的次数由栈的大小决定
  • JVM虚拟机栈(局部变量表与操作数栈) 虚拟机栈概述 由于跨平台性的设计,Java的指令都是根据栈来设计的。不同平台CPU架构不同,所以不能设计为基于寄存器的。 优点时跨平台,指令集小,编译器容易实现,缺点时...
  • 深入理解JVM虚拟机 第二章 java内存区域与内存溢出异常 2.2 运行时数据区2.2 运行时数据区1 概述2.2.1 程序计数器2.2.2 Java虚拟机栈栈帧1 局部变量表Solt2 操作数栈3 动态链接 2.2 运行时数据区 1 概述 运行时数据...
  • 概念首先得明白局部变量,静态局部变量,全局变量,静态全局变量这几个概念,以下面程序举例://main.cpp int a = 0; //全局变量 static int b=0;//静态全局变量 main() { int c; //局部变量 static int d;//静态...
  • 注意:物理上实现程序计数器是寄存器实现的,整个cpu中最快的一个执行单元 ④. 它是唯一一个java虚拟机规范中没有OOM的区域 解释: ⑤. 使用PC寄存器存储字节码指令地址有什么用呢? 为什么使用PC...
  • 1. 局部变量表的变量名是来的? 2. 局部变量表并不保存局部变量的值,那这个值是储存哪里的? 字节码指令`iload_2`的意思是拿出局部变量表中位置为2的变量,应该是拿值出来吧,可是这个值局部变量表并没有存啊...
  • 局部变量的位置分配

    2014-06-19 15:53:14
    局部变量保存栈里 栈和堆的区别是 栈是系统根据变量大小自动分配空间的 堆是你用new,malloc等手动分配空间的 局部变量保存栈内存区; 栈内存区的地址是连续的,由系统控制速度较快而 堆内存区的地址是不...
  • 局部变量和全局变量试题

    千次阅读 2011-03-28 08:47:00
    对于有些编译器而言,同一个函数内可以定义多个同名的局部变量,比如两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就那个循环体内。2、如何引用一个已经定义过的全局变量?答:extern可以用...
  • 1.基本类型的 变量 a 和他所指向的值 1是存在栈里还是方法区的常量池中。 2.a中存的是1的值还是地址?
  • 一、实例变量 也叫成员变量、全局变量。 定义类中、方法外,有默认初始值。 通过对象的引用来访问实例变量。 随着对象的建立而建立,随着对象的消失而消失,存在于对象所在的堆内存中。...三、局部变量 定义方法
  • 局部变量表(Local Variables)(简而言之就是方法内部定义的形参、局部变量值、返回值) 代码示例 关于slot(槽)的理解 Slot的重复利用 静态变量与局部变量的对比 变量的分类 补充说明 操作数栈(用数组来...
  • 局部变量太大导致栈溢出

    万次阅读 2016-07-17 12:18:24
    局部变量太大导致栈溢出问题: 昨天,有同学遇到栈溢出的问题。做大三小学期项目时,需要一个750x750的矩阵。于是栈中定义了一个二维数组。为了说明问题,做如下简化: /* 测试环境: window平台 vs2013 */int ...
  • 实参、形参、局部变量和全局变量

    千次阅读 2020-09-15 16:53:39
    目录实参和形参实参数据传递函数调用过程形参实参和形参的关系局部变量和全局变量局部变量局部变量的作用域说明:全局变量全局变量说明: 实参和形参 实参 实际参数简称“实参”。调用有参函数时,函数名后面括号...
  • 好基础的问题,居然没答...栈由操作系统(编译器)自动分配释放释放空间,用于存放函数的参数值、局部变量 int main() { int a; //栈 char s[] = "str"; //栈 char *p2; //栈 } 函数中定义的局部变量按照先后定...
  • 函数中定义大数组(局部变量)的问题 今天调程序时(我用的是DSP处理器),函数内部定义了两个较大的数组:float a[300],float[300],编译无错也无警告, 但运行时程序会出错,像是跑飞的样子,后来我将这两个...
  • 西门子S7-1200PLC局部变量相关知识

    千次阅读 2019-05-06 14:23:00
    什么是局部变量呢?回答这个问题之前,有必要对变量声明有一个基本了解。TIA Portal STEP7中有两种用来定义符号地址的表格形式:符号(共享符号)和变量声明(局域符号),其本质都是为了建立绝对地址与...
  • 文章目录一、存储区域介绍二、ubuntu系统中输出信息进行验证三、Keil中针对stm32系统进行验证四、总结五、参考资料 ...栈区(stack)–由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类
  • SQL中,我们常常使用临时来存储临时结果,对于结果是一个集合的情况,这种方法非常实用,但当结果仅仅是一个数据或者是几个数据时,还要去建一个,显得就比较麻烦,另外,当一个SQL语句中的某些元素经常变化时...
  • java:【局部变量、成员变量和构造器】

    万次阅读 多人点赞 2014-03-27 10:34:57
    前言 因为谈构造器,可定涉及到super关键字和this关键字。 其中This指的是当前对象的引用,super是当前对象里面的父类对象的...因为子类隐藏了父类的成员变量或者重写了父类的方法后,有时还有可能要用父类的成员变量
  •  全局变量也称为外部变量,是函数外部定义的变量。它不属于一个函数,它属于一个源程序文件。其作用域是整个源程序。函数中使用全局变量,应该做全局变量说明。只有函数内经过说明的全局变量才能使用。但...
  • SQL中的全局变量和局部变量(@@/@)

    千次阅读 2011-04-08 11:07:00
    SQL中的全局变量和局部变量(@@/@)
  • 前言 因为谈构造器,可定涉及到super关键字和this关键字。 其中This指的是当前对象的引用,super是当前对象里面的父类对象的引用。...因为子类隐藏了父类的成员变量或者重写了父类的方法后,有时还有可能...
  •  接触过设计模式的读者,会经常看到这样的场景:实例化A类的时候,需要B类作为构造方法的参数,这说明A类需要持有一个B类的引用。比如代理模式、装饰模式等,都会这样做。例如Java中的IO流采用的就是装
  • SQL Server 表变量和临时的区别

    千次阅读 2017-07-05 23:11:25
    SQL Server 表变量和临时的区别
  • 太无耻了吧,都没给别人分,,,, 程序中的局部变量是编译时候分配地址的还是运行时分配的呢?...按照我的理解,局部变量栈中分配的,应该是运行时分配地址的,不知道对不对? 栈是一种先进后出的数据...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 77,355
精华内容 30,942
关键字:

局部变量表在哪