java方法体的变量内存分配
2016-08-17 17:49
183 查看
java方法体的变量作为返回值的原理
在读《代码大全》时看到,c语言在方法中不要返回指向局部变量的指针,想到了java中是可以返回任意类型,没有限制,这是怎么实现的。经过深入了解,c语言是可以返回局部变量指针,但是这个指针地址必须不是指向栈内存。java为什么可以返回任意类型,因为java控制了引用类型不允许在栈内存中创建,java在栈的内存分配上设定了栈只存放基本类型的变量数据和引用类型的引用。1.java方法的返回类型
1.void 无返回值;2.基本类型 byte、short、int、long、float、double、boolean、char;
3.引用类型 String、Enum、类等;
由于void没有返回值,不需要考虑,需要讨论的是返回值是基本类型和引用类型的实现原理。
2.java运行时的数据存储
1.寄存器(register) 存取速度最快,编译器根据需求进行分配,我们在程序中无法控制;2.栈(stack) 存取速度比较快,存放基本类型的变量数据和引用类型的引用;(注意引用类型本身不存放在栈中)
3.堆(heap) 存取速度较慢,运行时动态分配内存,存放对象实例,New的对象实例、数组等;
4.静态存储(static storage) 存储static关键字修饰的数据;
5.常量池(Constant Pool Table) 存放各种字面量和符号引用;
方法返回值的的数据存储基本使用基本类型-栈(stack)和引用类型-堆(heap) 。
3.java方法返回值的原理
public int isNotEmpty(String s){ if(null!=s && s.length()>0) return 1; return 0; }
返回类型当时值类型,假如需要执行这个方法时,JVM线程的栈中会创建一个栈帧,把这个方法的局部变量表、操作数栈、动态链接、方法出口等信息存储到栈帧中,isNotEmpty方法的执行就是栈帧在虚拟机栈中从入栈到出栈的过程,方法执行完毕后,释放掉栈帧占用的内存,返回值消失。
public static void main(String[] args){ int a=isNotEmpty(null); }
现在调用isNotEmpty方法并把返回值赋值给一个整形变量,这时在执行到方法的出口时,方法会把返回的值复制一份,put到main函数的栈中,isNotEmpty方法执行完毕后,释放掉栈帧占用的内存,然后进行赋值运算。
public static void main(String[] args){ int arr[]=getArray(); } public int[] getArray(){ int a[]=new int[]{1,2}; return a; }
如果这时返回类型是引用类型,是怎么实现的,int a[]在getArray方法执行时,在堆中申请内存空间存储数据,然后数组a指向该内存地址,在getArray方法的栈帧中存放的是数组a地址,这时这个地址相当于值类型了,在getArray方法执行到方法的出口时,把地址的值复制一份,put到main函数的栈中,方法执行完毕后,释放掉栈帧占用的内存,这时数组a消失,但是数组a在堆中申请的空间并没有被GC回收,执行赋值操作后,数组arr的地址就指向了数组a申请的空间。这就实现了返回引用类型。
相关文章推荐
- java内存分配及变量存储
- java中有关“变量”内存分配问题
- c语言 输出变量的地址,动态的观察内存的分配。
- c语言 变量的存储类别以及对应的内存分配?
- 内存分配:堆、栈、全局变量/静态变量、代码区
- 编译器对变量的内存分配方式
- 由swap看变量在内存中的分配
- 探讨C++ 变量生命周期、栈分配方式、类内存布局、Debug和Release程序的区别(二)
- 内存分配及变量存储位置(堆、栈、方法区常量池、方法区静态区)
- 程序在的内存中的分配(常量,局部变量,全局变量,程序代码)
- C语言中的全局变量内存分配和初始化顺序
- C\C++编译器关于变量的内存分配顺序总结
- Java static 变量、方法的什么时候分配内存
- java 内存分配及变量存储位置的区别
- C++各种变量内存分配
- 验证vector变量是在内存中怎么分配的
- 内存分配: 类变量、实例变量、成员变量、局部变量
- C语言定义了一个结构体怎么分配内存?C\C++中结构体变量与结构体指针内存分配问题?
- J2SE_变量内存分配机制
- 内存分配及变量存储位置(堆、栈、方法区常量池、方法区静态区)