关于Java成员变量、局部变量、方法,在JVM的内存空间分配

x33g5p2x  于2022-02-18 转载在 Java  
字(2.6k)|赞(0)|评价(0)|浏览(458)

1、变量类型


2、类的结构
下面是一般类的结构

  1. //类体=属性+状态(即:类体=变量+方法)
  2. public class 类名{ //类名最好首字母大写的英文
  3. String name; //在方法体外,所以是成员变量
  4. //下面是一个main方法(程序入口的主方法)
  5. public static void main(String[] args){
  6. int i; //在main方法体内,所以是局部变量
  7. }
  8. }

3、类的编译运行时JVM内存的变化

JVM(Java 虚拟机)主要包括三个内存空间。分别是:栈内存、堆内存、方法区内存。(堆内存和方法区内存各一个。一个线程一个栈内存)

首先类编译后产生.class的字节码文件,执行类加载器把.class的字节码文件加载到方法区内存(方法的代码片段以及整个类的代码片段都是存储到方法区内存当中)
找到类的程序入口(即主方法)执行到什么语句就会在对应的内存分配空间。

例如程序执行过程中使用new运算符创建的Java对象,存储在堆内存当中。对象内部有实例变量,所以实例变量也存储在堆内存当中。

方法调用的时候,该方法所需要的内存空间在栈内存中分配,称为压栈。方法执行结束后,该方法所属的内存空间释放,称为弹栈。
下面分析一下案例:

  1. public class Computer{
  2. double price; //价格
  3. String type; //型号
  4. }
  5. public class Student{
  6. int number; //学号
  7. String name; //姓名
  8. Computer com;
  9. }
  10. public class Test{
  11. public static void main(String[] args){
  12. /* “=”符号右边先执行 new Computer()严格来说是在堆内存里面开辟了一个新的Computer对象空间。
  13. 对象的空间地址给了一个名字叫computer的引用而已,引用类型就是第一个Computer。*/
  14. Computer computer=new Computer();
  15. /* “=”符号右边先执行 new Student()严格来说是在堆内存里面开辟了一个新的Student对象空间。
  16. 对象的空间地址给了一个名字叫student的引用而已,引用类型就是第一个Student。*/
  17. Student student=new Student();
  18. //student.com的引用指向了computer的引用地址(相当于将computer的引用地址给student.com的引用)
  19. student.com=computer;
  20. computer.price=4999.9;
  21. System.out.println(student.com.price); //4999.9
  22. System.out.println(student.com.type); //null,因为没有赋值,String默认值是null
  23. System.out.println(computer.price); //4999.9
  24. System.out.println(computer.type); //null,因为没有赋值,String默认值是null
  25. student.name="jack";
  26. m();
  27. System.out.println(student.number); //0,因为没有赋值,int默认值是0
  28. System.out.println(student.name); //jack
  29. }
  30. public static void m(){
  31. String str="handsome";
  32. System.out.println("I am really "+str);
  33. }
  34. }
  35. 下面是运行结果:
  36. ---------------------------------
  37. 4999.9
  38. null
  39. 4999.9
  40. null
  41. I am really handsome
  42. 0
  43. jack

以上有三个类分别是Computer类、Student类、Test类、编译运行将产生Computer.class、Student.class、Test.class的字节码文件。因为还用到String类,所以String.class等字节码文件一起载入到方法区,然后找到程序入口main,方法main被压栈。

Computer computer=new Computer(); 在堆里创建Computer 对象,实例变量有price和type,然后对象的地址0x1234给到引用computer。引用computer在main方法里面,所以引用computer在栈。Student student=new Student(); 也跟上面一样。

student.com=computer; 是将computer的地址0x1234给到Student对象的com实例变量里。所以student.com.price是student指向的0x2451地址找到com,com指向的0x1234地址找到price;computer.price是computer指向的0x1234地址找到price;虽然结果是相同的,但是student.com.price可以体现关联性

computer.price=4999.9; 与 student.name=“jack”;都是将地址给到对应的引用上。接下来然后遇到m();的调用,把它压栈,方法里面的局部变量也在栈里面,方法m();执行完弹栈,跟随的局部变量str也失效。然后执行完代码mian方法也弹栈。(先进后出,后进先出)

扩展
  • 访问实例变量的语法格式:
    读取数据——>引用.变量名;修改数据——>引用.变量名=值;
  • 数据类型:
    数据类型分为基本数据类型(byte short int long float double boolean char)和引用数据类型(开发包的类(String…等)以及自己定义的类)
    数据类型的默认值

  • 三块内存当中变化最频繁的是栈内存,最先有数据的是方法区内存,垃圾回收器主要针对的是堆内存。
  • 垃圾回收器(自动垃圾回收机制、GC机制)什么时候会考虑将某个Java对象的内存回收呢?
  1. 问:什么时候堆内存中的Java对象会变成垃圾呢?
  2. 答:没有更多的引用指向它的时候
  3. 答:这个对象无法被访问,因为访问对象只能提通过引用的方式访问
  • 空引用访问“实例“相关的数据一定会出现空指针异常。

以上是个人对JVM的理解,若有错误欢迎指出

相关文章

最新文章

更多