1. CPU 工作原理
CPU的运行原理就是:控制单元在时序脉冲的作用下,将指令计数器里所指向的指令地址(这个地址是在内存里的)送到地址总线上去,然后CPU将这个地址里的指令读到指令寄存器进行译码。对于执行指令过程中所需要用到的数据,会将数据地址也送到地址总线,然后CPU把数据读到CPU的内部存储单元(就是内部寄存器)暂存起来,最后命令运算单元对数据进行处理加工。周而复始,一直这样执行下去。
多个物理CPU,CPU通过总线进行通信,效率比较低。
多核CPU,不同的核通过L2 cache进行通信,存储和外设通过总线与CPU通信
计算过程。程序以及数据被加载到主内存;指令和数据被加载到CPU的高速缓;CPU执行指令,把结果写到高速缓存;高速缓存中的数据写回主内存
2. java内存模型
- 堆(Heap):线程共享。所有的对象实例以及数组都要在堆上分配。回收器主要管理的对象。
- 方法区(Method Area):线程共享。存储类信息、常量、静态变量、即时编译器编译后的代码。
- 虚拟机栈(JVM Stack):线程私有。存储局部变量表、操作栈、动态链接、方法出口,对象指针。
- 本地方法栈(Native Method Stack):线程私有。为虚拟机使用到的Native 方法服务。如Java使用c或者c++编写的接口服务时,代码在此区运行。
- 程序计数器(Program Counter Register):线程私有。有些文章也翻译成PC寄存器(PC Register),同一个东西。它可以看作是当前线程所执行的字节码的行号指示器。指向下一条要执行的指令。
- JDK 8 增加 元数据区 Metaspace , 直接操作 物理内存
垃圾回收 清理堆内存
YoungGC 是 小回收, 时间快
FullGC 是 大回收, 时间慢
多次 YGC , 依然存活的对象, 超过一定次数(阈值), 会晋升到 Old 区
如果 FGC 后依然放不下, 会报 内存溢出异常(OOM)
Young GC的触发时机:Young GC其实一般就是在新生代的Eden区域满了之后就会触发,采用复制算法来回收新生代的垃圾。
Full GC的触发时机如下:
(1)发生Young GC之前进行检查,如果“老年代可用的连续内存空间” < “新生代历次Young GC后升入老年代的对象总和的平均大小”,说明本次Young GC后可能升入老年代的对象大小,可能超过了老年代当前可用内存空间
此时必须先触发一次Old GC给老年代腾出更多的空间,然后再执行Young GC。
(2)执行Young GC之后有一批对象需要放入老年代,此时老年代就是没有足够的内存空间存放这些对象了,此时必须立即触发一次Old GC。
(3)老年代内存使用率超过了92%,也要直接触发Old GC,当然这个比例是可以通过参数调整的。
概括成一句话,就是老年代空间也不够了,没法放入更多对象了,这个时候务必执行Old GC对老年代进行垃圾回收。
通过 cmd -> jconsole / jvisualvm 监控内存 变化
jvisualvm 工具->插件->visual GC
如果版本url 错误 , 到https://visualvm.github.io/pluginscenters.html 查找对应 url
3.native 是什么
认识 native 即 JNI,Java Native Interface
凡是一种语言,都希望是纯。比如解决某一个方案都喜欢就单单这个语言来写即可。Java平台有个用户和本地C代码进行互操作的API,称为Java Native Interface (Java本地接口)。
简单地讲,一个Native Method就是一个java调用非java代码的接口。
4. Java中的volatile 变量是什么?
volatile是一个特殊的修饰符,只有成员变量才能使用它。在Java并发程序缺少同步类的情况下,多线程对成员变量的操作对其它线程是透明的。volatile变量可以保证下一个读取操作会在前一个写操作之后发生。线程都会直接从内存中读取该变量并且不缓存它。这就确保了线程读取到的变量是同内存中是一致的。
5.并发和并行
并发 : Concurrency,即一段时间内多个任务在执行,但不一定是同时在执行,它们可能是交替在运行,也有可能是串行运行的。
并行 : Parallelism,这个就是多个任务在同时执行,可以理解为并发里面有一部分任务在并行执行。
单核CPU不会有并行操作,应为一个CPU一次只能执行一条指令,并行操作只存在于多核CPU中。
6.同步和异步
同步 : Synchronous,即调用方法开始,一旦调用就必须等待方法执行完返回才能继续下面的操作。
举个例子 : 你去银行ATM取钱,你必须等到ATM吐完钱你拿到钱取完卡你才能离开。
异步 : Asynchronous,即不关心方法执行的过程,触发要调用的方法就继续执行下面的操作,不会像同步那样阻塞直要到方法完成才继续。
举个例子 : 你这次要取钱,数量较大,你直接电话或者APP预约银行说你要取多少万现金,这段时间银行会为你准备钱,而这与你都没什么关系,然后你只要按预定的时候去取就行了,对你于而言,你们是触发了一个异步动作而已。