面试题:
1.jvm的内存模型:
1.程序计数器:是一块较小的内存空间,它可以看成当前线程所执行的字节码的行号指示器。线程私有的,每条线程都有一个程序计数器;
2.java虚拟机栈:也是线程私有的,存储的是基本数据类型与对象的引用
3.java本地方法栈 :线程私有的
4.java堆:线程共享的,也是垃圾回收的主要场所,分为新生代和老年代,主要存放的是数组和用new创建的对象。
5.方法区:线程共享的,运行时常量池就是方法区的一部分。主要存放final常量,static常量。方法区中主要为永久代,内存回收效率低。
java堆主要分为年轻代和老年代:
年轻代:
所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。年轻代分三个区。一个Eden区,两个Survivor区(一般而言)。大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor区也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制“年老区(Tenured)”。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。而且,Survivor区总有一个是空的。同时,根据程序需要,Survivor区是可以配置为多个的(多于两个),这样可以增加对象在年轻代中的存在时间,减少被放到年老代的可能。
老年代:
在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。
持久代:
用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些Class,例如Hibernate等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=进行设置。