jvm从内存模型到垃圾收集器

1. JVM是Java Virtual Machine(Java虚拟机)的缩写。

是整个java实现跨平台的最核心的部分,能够运行以Java语言写作的软件程序。

2. jvm 运行时数据区

这里写图片描述
这里写图片描述

3. Java 8的内存分代改进

从永久代到元空间,在小范围自动扩展永生代避免溢出。

4. JVM垃圾回收机制

jVM中共划分为三个代:年轻代、年老代和持久代。 
年轻代:存放所有新生成的对象; 
年老代:在年轻代中经历了N次垃圾回收仍然存活的对象; 
持久代:用于存放静态文件,如Java类、方法等。 

新生代的GC为“minor gc”,老年代的GC”Full Gc 或者Major GC”;
其中用System.gc()强制执行的是Full Gc。 

判断对象是否需要回收的方法有两种: 
1.引用计数 
    当某对象的引用数为0时,便可以进行垃圾收集。 
2.对象引用遍历 
    如果对象不能从这些根对象到达,则将它作为垃圾收集。在对象遍历阶段,gc必须记住哪些对象可以到达,以便删除不可到达的对象,这称为标记(marking)对象。

触发GC(Garbage Collector)的条件: 
 1.GC在优先级最低的线程中运行,一般在应用程序空闲即没有应用线程在运行时被调用。 
 2.Java堆内存不足时,GC会被调用。

新生代中Eden和Survivor的比例分配等:
   默认比例8:1;大部分对象都是朝生夕死。 
   复制算法的基本思想就是将内存分为两块,每次只用其中一块,当这一块内存用完,就将还活着的对象复制到另外一块上面。复制算法不会产生内存碎片。

5. 对Java内存模型的理解,以及其在并发中的应用

Java内存模型的主要目标: 定义程序中各个变量的访问规则。 
Java线程之间的通信由Java内存模型(本文简称为JMM)控制。 
所有变量的存储都在主内存,每条线程还都有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝。
线程对变量的所有操作必须在工作内存完成,而不能直接读取主内存中的变量。
不同的线程直接无法访问对方工作内存中的变量,线程间变量的传递均需要通过主内存来完成。
线程间通信: 
  1.首先,线程A把本地内存A中更新过的共享变量刷新到主内存中去。 
  2.然后,线程B到主内存中去读取线程A之前已更新过的共享变量。

这里写图片描述

6. 指令重排序,内存栅栏等

指令重排序:编译器或运行时环境为了优化程序性能而采取的对指令进行重新排序执行的一种手段。
在单线程程序中,对存在控制依赖的操作重排序,不会改变执行结果;但在多线程程序中,对存在控制依赖的操作重排序,可能会改变程序的执行结果。   
volatile修饰(原子性操作),不会进行指令重排序。

7. volatile的语义,它修饰的变量一定线程安全吗

一个变量被定义为volatile之后,具备两重语义:
①保证此变量对所有线程的可见性,即当一条线程修改了这个值,新值对于其他所有线程来说是立即得知的,普通变量需要通过主内存传递。
②禁止指令重排序优化。 
Volatile修饰的变量不一定是线程安全的,eg非原子操作a++等。

8. g1和cms区别,吞吐量优先和响应优先的垃圾收集器选择

CMS收集器:一款以获取最短回收停顿时间为目标的收集器,是基于“标记-清除”算法实现的。分为4个步骤:初始标记、并发标记、重新标记、并发清除。 
G1收集器:面向服务端应用的垃圾收集器,过程:初始标记;并发标记;最终标记;筛选回收。整体上看是“标记-整理”,局部看是“复制”,不会产生内存碎片。 
吞吐量优先的并行收集器:以到达一定的吞吐量为目标,适用于科学技术和后台处理等。 
响应时间优先的并发收集器:保证系统的响应时间,减少垃圾收集时的停顿时间。适用于应用服务器、电信领域等。

9. classpath的理解

classpath是javac编译器的一个环境变量。它的作用与import、package关键字有关。 
package的所在位置,就是设置CLASSPATH当编译器面对import packag这个语句时,它先会查找CLASSPATH所指定的目录,并检视子目录java/util是否存在,然后找出名称吻合的已编译文件(.class文件)。如果没有找到就会报错! 
动态加载包

猜你喜欢

转载自blog.csdn.net/besto229/article/details/81090221
今日推荐