欢迎光临散文网 会员登陆 & 注册

150天打卡day20_内存管理

2021-05-13 18:52 作者:关阿姨的Java日记  | 我要投稿

1.上节回顾

  • 内部类的定义

  • 成员内部类

  • 匿名内部类

2.内存管理

  • java的编译过程,编译期从.java文件编译成字节码.class文件,运行期又JVM(java虚拟机)加载.class文件,运行程序。所以Java程序都是要经过编译最后在JVM虚拟机中运行

  • 变量是在内存中存储数据的一块空间,程序中所有的数据都要用变量临时保存在内存中。

  • 学习数组,学习静态的时候也都会解释内存变化

程序中,无论是代码还是数据都要保存在内存中,而内存变化由运行程序的JVM来管理所需的内存空间。内存又分为三大块,分别是堆(heap)、栈、方法区。

2.1 堆内存

堆:可以理解为内存中一片分散的区域

堆内存在某种意义上来说是在内存中最灵活的,也是唯一可以让程序员主动控制的空间。因为堆内存里面存放的都是new出来的对象实例,用完之后靠垃圾回收器不定期的自动消除比如:

Human h1 = new Human();

  • 程序运行的时候会先执行等号右边的new Human();在内存中创建出一个h1对象,假设里面有两个属性,名字和年龄,地址为0x50;

  • 其实h1对象就是创建在堆内存中的,每new一次,就会开辟一块内存空间,而且每个对象都会有唯一的内存地址。

  • 由于每个对象都没有名字,只有地址,由引用变量保存,指向对象地址,大家先记住用来保存地址的引用变量是保存在栈中。

 

2.1.1. 对象生命周期

对象也是有生命周期的,当一个对象没有任何变量指向他的时候,就会被视为废弃的对象,就要等待被回收。对象中的成员变量也会等待回收。

所以对象和成员变量的的生命周期为:从对象在堆中被创建开始到对象从堆中被回收结束。

2.1.2 垃圾回收机制

在Java中会有一个自动回收的机制:叫垃圾回收器(Garbage  Collection),简称gc,他是JVM自带的一个线程(自动运行着的程序),用于回收没有任何引用指向的对象。

 

问题一:

既然gc会把废弃的对象自动回收掉,那会不会把成员变量也一并回收了?

2.1.3 内存泄漏

内存泄漏就是指不再使用的内存没有被及时的回收掉。严重的内存泄漏会因为过多的内存占用而导致程序奔溃。

例如:

Human h1 = new Human()Human ();

new出来的对象都存储在堆中,然后通过引用变量保存地址指向h1对象,假如有另一个

Human h2 = h1

 

问题二:

那么h2会不会新开辟一个空间?

问题三:

如果这时候h1=null的时候意味着c里面已经没有地址了,那对象算不算垃圾?

 

2.1.4.System.gc()方法

而gc的回收过程对于程序员来说是透明的,不一定说是发现了垃圾就会立马清除掉,所以呢这时候就需要程序员手动调用System.gc()方法来建议JVM尽快帮我们调用gc来回收垃圾。

2.2.栈内存

栈:可以理解为是内存中一片连续的区域

基本数据类型,局部变量都是存放在栈内存中,用完就消失。

JVM在其内存空间开辟一个称为”栈”的存储空间,用于存储程序运行时在方法中声明的所有的局部变量

  • 方法中的变量就是局部变量,是在栈内存中分配的,如果变量为基本类型,则在栈内存储的是该变量的值。如果变量为引用类型,则在栈中存储的是堆中的对象的地址。

  • 一个运行的Java程序从开始到结束可能会有多次方法的调用,而JVM会为每一个方法的调用在栈中分配一个对应的空间,这个空间称为是该方法的栈帧。而且一个栈帧对应一个正在调用中的方法,栈帧里面存放了这个方法的局部变量和参数。只有当方法调用完了,对应的栈帧也将会被清除,局部变量也随之失效。

例如:

class Add{  int numA;  void show(int numB){    int numC = 5;  } }

2.2.1.局部变量的生命周期

方法调用时,生命周期开始,方法结束调用后,生命周期结束

2.2.2.成员变量和局部变量

  • 成员变量

写在类中,方法外的叫成员变量,有默认的初始值,而且在类实例化的时候,存放在堆中,和对象的生命周期一样,对象失效时,成员变量也一并失效。

class Add{  int numA; }

  • 局部变量:

写在方法里面的,包括参数都叫做局部变量,没有默认的初始值,必须自己设定初始值,方法被调用时,存在栈中,方法调用完了,就从栈中清除了。

 

2.3.方法区

方法区是各个线程共享的内存区域,用于存储已经被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据

  • 方法区里存的是.class的字节码文件,一旦程序运行的时候,有个类装载器会先加载.class字节码信息,而经过解析后装在方法区中,所以方法区中存的是字节码文件、方法和静态变量.

  • 方法区中的内容在类存在的时候就已经有了,所以只会加载一次

方法只有一份,通过this来区分具体的对象,谁调用就用this

 

 

 

 

 

 

 

 


150天打卡day20_内存管理的评论 (共 条)

分享到微博请遵守国家法律