Maven笔记

基础

安装

  • 需要java sdk、Maven
  • 如果使用idea安装则没有对path进行写入,需要手动写入。
    • M2_HOME:C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\plugins\maven\lib\maven3
    • MAVEN_HOME:C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\plugins\maven\lib\maven3
    • Path:%M2_HOME%/bin

JVM学习笔记11:synchronized的实现

synchronized作用于代码块与函数

  • 当声明 synchronized 代码块时,编译而成的字节码将包含 monitorenter 和 monitorexit 指令。这两种指令均会消耗操作数栈上的一个引用类型的元素(也就是 synchronized 关键字括号里的引用),作为所要加锁解锁的锁对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public void foo(Object lock) {
synchronized (lock) {
lock.hashCode();
}
}
// 上面的 Java 代码将编译为下面的字节码
public void foo(java.lang.Object);
Code:
0: aload_1
1: dup
2: astore_2
3: monitorenter
4: aload_1
5: invokevirtual java/lang/Object.hashCode:()I
8: pop
9: aload_2
10: monitorexit
11: goto 19
14: astore_3
15: aload_2
16: monitorexit
17: aload_3
18: athrow
19: return
Exception table:
from to target type
4 11 14 any
14 17 14 any

JVM学习笔记10:内存模型

概念

  • 个人感觉这个内存模型的名称很让人迷惑,开始理解的模型是一个数据结构,但是明显这里的内存模型是一个套解决内存可见性和代码乱序执行的技术方案。
  • PS:《深入理解java虚拟机:jvm高级特性与最佳实践》中提到的:Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。

JVM学习笔记9:垃圾回收

引用计数法与可达性分析

  • 引用计数没啥可说的,就是对堆中的对象记录有多少对象来持有它。在我的理解中最多的应该还是变量来引用,还有如果是与native的代码交互,可能还有指针来持有。

  • 可达性是用来解决互相引用问题的,这个算法的实质在于将一系列 GC Roots 作为初始的存活对象合集(live set),然后从该合集出发,探索所有能够被该集合引用到的对象,并将其加入到该集合中,这个过程我们也称之为标记(mark)。最终,未被探索到的对象便是死亡的,是可以回收的。

  • 那么什么是 GC Roots 呢?我们可以暂时理解为由堆外指向堆内的引用,一般而言,GC Roots 包括(但不限于)如下几种:

    • Java 方法栈桢中的局部变量;
    • 已加载类的静态变量;
    • JNI handles;
    • 已启动且未停止的 Java 线程。

JVM学习笔记8:Java对象的内存布局

对象创建方式

  • 6种方法创建对象,但是不同的方法对于实例字段的初始化是不同的:
    • 直接复制已有的数据到实例化字段:Object.clone 方法和反序列化
    • 没有初始化实例字段:Unsafe.allocateInstance
    • 通过调用构造器来初始化实例字段: new 语句和反射机制

JVM学习笔记7:invokedynamic

问题的产生

  • 在java中实现动态语言的能力
  • Java 7 引入了一条新的指令 invokedynamic。该指令的调用机制抽象出调用点这一个概念,并允许应用程序将调用点链接至任意符合条件的方法上
    作为 invokedynamic 的准备工作,Java 7 引入了更加底层、更加灵活的方法抽象 :方法句柄(MethodHandle)。

JVM学习笔记6:反射

反射的实现

  • 横向比对C#,几乎是是一样的

核心是invoke函数

1
2
3
4
5
6
7
8
9
10
11
public final class Method extends Executable {
...
public Object invoke(Object obj, Object... args) throws ... {
... // 权限检查
MethodAccessor ma = methodAccessor;
if (ma == null) {
ma = acquireMethodAccessor();
}
return ma.invoke(obj, args);
}
}

JVM学习笔记5:异常处理

异常的分类

  • 显式:主体是应用程序,它指的是在程序中使用“throw”关键字,手动将异常实例抛出。
  • 隐式:主体则是 Java 虚拟机,它指的是 Java 虚拟机在执行过程中,碰到无法继续执行的异常状态,自动抛出异常。举例来说,Java 虚拟机在执行读取数组操作时,发现输入的索引值是负数,故而抛出数组索引越界异常(ArrayIndexOutOfBoundsException)。

JVM学习笔记4:方法调用

重载与重写

  • 重载的方法在编译阶段完成识别,调用是根据参数声明类型选择重载方法。选择分三个阶段:

    • 在不考虑对基本类型自动装拆箱(auto-boxing,auto-unboxing),以及可变长参数的情况下选取重载方法;
    • 如果在第 1 个阶段中没有找到适配的方法,那么在允许自动装拆箱,但不允许可变长参数的情况下选取重载方法;
    • 如果在第 2 个阶段中没有找到适配的方法,那么在允许自动装拆箱以及可变长参数的情况下选取重载方法。
  • 如果 Java 编译器在同一个阶段中找到了多个适配的方法,那么它会在其中选择一个最为贴切的,而决定贴切程度的一个关键就是形式参数类型的继承关系。

  • 下面代码中第一次调用会是函数2,因为null可以匹配object和string,但是因为string是Object的子类,所以编译器认为string合适。

JVM学习笔记3:类加载

知识点

  • 基本步骤:经过加载、链接以及初始化三大步骤。其中,链接过程中同样需要验证;而内存中的类没有经过初始化,同样不能使用。
  • 引用类型与CLR基本一致,泛型会被编译为特定类型的代码。类和接口是字节码。数组类是由 Java 虚拟机直接生成的,这个似乎没有CLR中对标的东西。
  • 加载用的字节流可以来自java编译后的class,也可以是网络比如网页中内嵌的小程序 Java applet。字节流我理解就是IL,而且从结果看也确实就是这个东西。
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×