架构师训练营第九周

用户头像
Melo
关注
发布于: 2020 年 07 月 30 日

JVM

概述:

Java: Compile once, run everywhere.

但操作系统是各不相同的,所以可以通过增加一个中间层(虚拟层)来解决问题。也就是虚拟机。Java .class Bytecode magic word: CAFEBABE。 计算机常用的技巧:特殊编码来标识。

在代码执行时,JVM将Bytecode解释执行,屏蔽对底层操作系统的依赖,JVM也可以将bytecode编译执行,如果是热点代码,会通过JIT动态的编译为机器码,提高效率。

一张图搞清楚栈,堆,方法区:
线程工作内存 & volatile:

Java内存模型规定在多线程情况下,线程操作主内存变量,需要通过线程独有的CPU cache拷贝主内存变量副本来进行。



一个共享变量(类的成员变量,类的静态成员变量)被volatile修饰之后:

  • 保证了不通线程对于这个变量进行操作时的可见性。一个线程修改了某个变量的值,这个新值对其他线程来说都是立即可见的。当一个线程向被volatile关键字修饰的变量写入数据的时候,虚拟机会强制它被值刷新到主内存中。当一个线程用到被volatile关键字修饰的值的时候,虚拟机会强制要求它从主内存中读取

  • 屏蔽指令重排序:指令重排序是编译器和处理器为了高效对程序进行优化的手段,它只能保证程序执行的结果时正确的,但是无法保证程序的操作顺序与代码顺序一致。这在单线程中不会构成问题,但是在多线程中就会出现问题。非常经典的例子是在单例方法中同时对字段加入voliate,就是为了防止指令重排序。

JVM垃圾回收:

可达性分析算法:从线程栈中的局部变量,或者是方法区的静态变量出发,将这些变量引用的对象进行标记,以此递归。标记过的对象就是被使用的对象。



清理 - 压缩 - 复制

清理: 将垃圾对象占用的内存空间标记为空闲,记录在空闲列表里以复用。

压缩:存活的对象从堆的头部开始占用连续空间。

复制: 将堆空间分成两个部分,只在其中一部分创建对象,当这个部分空间用完的时候,记过的可用对象复制到另一个空间里。



垃圾回收的堆结构:



JVM垃圾回收器算法:



主流的:G1垃圾回收器

思路:堆分成小块空间,并行发现存活对象,更短的停顿。





Minor GC:

Collecting garbage from Young space (consisting of Eden and Survivor spaces) is called a Minor GC. Minor GC is always triggered when JVM is unable to allocate space for a new Object, e.g. the Eden is getting full. Whenever the pool is filled, its entire content is copied and the pointer can start tracking the free memory from zero again. So instead of classical Mark, Sweep and Compact, cleaning Eden and Survivor spaces is carried out with Mark and Copy instead. So, no fragmentation actually takes place inside Eden or Survivor spaces. The write pointer is always residing on the top of the used pool. Against common belief, all Minor GCs do trigger stop-the-world pauses, stopping the application threads. For most of the applications, the length of the pauses is negligible latency-wise. 



Major GC/Full FC: 涉及了Tenured space. 区别是模糊的。

Java编程技巧:
  1. 最佳线程数 = [任务执行时间 / (任务执行时间 - I/O等待时间)] * CPU内核数

  2. 如果某个方法中创建的对象不会逃逸出该方法,那么它就是线程安全的。

  3. Servlet是线程安全的吗?https://www.cnblogs.com/chanshuyi/p/5052426.html

  4. ThreadLocal

既是线程共享的,也是独享的。

public static ThreadLocal myThreadLocal = new ThreadLocal(); -- 共享,object在堆

但是get(), set()都是本线程的操作。 --独享。



实现源码:

public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}



  1. Java的内存泄露

参考资料:

https://blog.csdn.net/anxpp/article/details/51325838



搜索引擎

倒排索引: 对于每个词,记录出现在哪些文档中。

带词频率与位置的倒排索引。(DocID; TF; <POS>)



Lucene架构:



Lucene不支持分布式。更大的数据量一般用ElasticSearch。



ElasticSearch

  • API简单高级

  • 索引备份,实现高可用

  • 索引分片,实现分布式



用户头像

Melo

关注

还未添加个人签名 2019.09.17 加入

还未添加个人简介

评论 (1 条评论)

发布
用户头像
请添加“极客大学架构师训练营标签”,便于分类~
2020 年 08 月 03 日 14:24
回复
没有更多了
架构师训练营第九周