面试准备:(栈内存&&堆内存&&常量池&&线程池)

栈内存:

指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。)          

            用于存储局部变量和对象的引用变量,每个线程之间都会有一个独立的栈空间,所以线程之间是不共享数据的。

定义的一些基本类型的变量和对象的引用变量都在栈内存中分配。在一段代码块定义一个变量时,java就在栈中为这个变量分配内存空间,超出作用域后,java自动释放分配内存空间。

堆内存:

一般用于存放不放在当前方法栈中的那些数据,例如,使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。

            用于存储实例化的对象,数组,JVM动态分配内存空间。一个JVM只有一个堆内存,线程之间可以共享数据

            New出来的对象和数组在堆中分配内存,由虚拟机中的自动垃圾回收机制管理

栈与堆的共同点和优缺点:

1:俩者都是存放数据的地方,java自动管理和释放,程序员不用直接的设置,更加方便。

2:栈的优势:

              存取速度比堆快,存在栈中的数据可以共享

3:缺点:

              数据大小与生存期必须是确定的,缺乏灵活点

备注:

1:从JVM认识堆栈:

Stack(栈)是JVM的内存指令区。Java 基本数据类型,Java 指令代码,常量都保存在Stack中。

Heap(堆)是JVM的内存数据区。每次分配不定长的内存空间,专门用来保存对象的实例。

2:JVM空间分配

堆:1、手动申请和释放空间2、空间比栈大

栈:1、自动分配和释放2、空间有限

例:在Java中,若只是声明一个对象,则先在栈内存中为其分配地址空间,若再new一下,实例化它,则在堆内存中为其分配地址。

3:回收上区别:

栈的内存管理是顺序分配的,而且定长,不存在内存回收问题。

堆则是随机分配内存,不定长度,存在内存分配和回收的问题。

在JVM中另有一个GC进程,定期扫描堆,进行释放,这就是垃圾回收机制。

常量池:

          1:常量:

final修饰的成员变量表示常量,值一旦给定就无法改变

final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量

       2:静态常量池运行时常量池。

 静态常量池,即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。

运行时常量池,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。

优点:

常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中。

  • 节省内存空间:常量池中所有相同的字符串常量被合并,只占用一个空间。

  • 节省运行时间:比较字符串时,==比equals()快。对于两个引用变量,只用==判断引用是否相等,也就可以判断实际值是否相等。

线程池:

java提供的四种线程池:

1. newSingleThreadExecutor:

创建一个单线程的线程池。这个线程池只有一个线程在工作。一个线程池中只能跑一个线程,单线程串行执行任务,但一个任务完成后才能进行下一个任务。

2.newFixedThreadPool:

可以规定线程池的大小,小于这个数量就创建新线程。当达到这个数量,就只能有这些线程,别的任务等待运行的任务结束再使用线程。

3. newCachedThreadPool(推荐用这个):

线程池的大小是根据jvm的大小而定的。当线程池的大小(核心线程池大小就是创建线程池的时候默认创建几个线程)大于正在执行的任务的数量的时候,会去自动释放那些空闲的线程,当任务增加,回去新添加线程。

4.newScheduledThreadPool:

支持任务调度的线程池。

优点:

可以并行的执行多个线程,提高效率。这里的提高效率,不是说提高系统的性能,而是每个线程都有相应的带宽,多线程就是充分利用cpu资源。

一般功能较复杂(用户注册,其他的操作放到多线程中,不然用户体验很不好)或者需要轮询操作的方法用到多线程。

猜你喜欢

转载自blog.csdn.net/qq_31051117/article/details/88054884