垃圾收集器

可达性分析算法

通过一系列的称谓 GC Roots 的对象作为起始点, 从这些节点开始向下搜索, 搜索所有走过的路径为引用链, 当一个对象到 GC Roots 没有任何引用链项链时, 则证明此对象时不可用的。

Java 语言中, 可作为 GC Roots 的对象包括下面几种:

  1. 虚拟机栈 (栈帧中的本地变量表) 中引用的对象
  2. 方法区中类静态属性引用的对象
  3. 方法区中常量引用的对象
  4. 本地方法栈中 JNI(即一般说的 Native 方法) 引用的对象

引用类型

从 JDK1.2 之后, Java 对引用的概念进行了扩充, 将引用分为强引用, 软引用, 弱引用, 虚引用, 这四种引用的强度一次逐渐减弱。

  1. 强引用就是指在程序代码之中普遍存在的, 类似 “Object obj = new Object()” 这类的引用, 只要强引用还存在, 垃圾回收器永远不会回收掉被引用的对象。
  2. 软引用是用来描述一些还有用但并非需要的对象, 对于软引用关联着的对象, 在系统将要发生内存异常之前, 将会把这些对象列进回收范围之中进行第二次回收, 如果这次回收还没有足够的内存, 才会抛出内存异常。
  3. 弱引用也是用来描述非必需对象的, 但是它的强度比软引用更弱一些, 被弱引用关联的对象只能生存岛下一次垃圾收集发生之前, 当垃圾收集器工作时, 无论当前内存释放足够, 都会回收掉只被弱引用关联的对象。
  4. 虚引用也称为幽灵引用或者幻影引用, 它是最弱的一种引用关系, 一个对象是否有虚引用的存在, 完全不会对其生存时间构成影响, 也无法通过虚引用来取得一个对象实例, 对一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。
阅读全文 »

运行时数据区域

运行时数据区域

程序计数器

字节码解释器通过更改这个计数器的值来选取下一条需要执行的字节码指令。每条线程都需要一个独立的程序计数器, 线程之间, 互不影响。Java虚拟机规范中唯一一个没有规定任何OutOfMemoryError情况的区域

阅读全文 »

数组的扩展

Array.from()

Array.from 方法用于将两类对象转为真正的数组:

  • 类似数组的对象( array-like object)
  • 可遍历( iterable) 的对象( 包括ES6新增的数据结构Set和Map)

Array.from 还可以接受第二个参数, 作用类似于数组的 map 方法, 用来对每个
元素进行处理, 将处理后的值放入返回的数组。

1
Array.from(arrayLike, x => x * x);
阅读全文 »

查看反编译代码

对以下代码进行反编译:

1
2
3
4
5

for (Integer i : list) {
System.out.println(i);
}

反编译后:

1
2
3
4
5
6

Integer i;
for(Iterator iterator = list.iterator(); iterator.hasNext(); System.out.println(i)){
i = (Integer)iterator.next();
}

阅读全文 »

使用香港Google

1
https://www.google.com.hk/ncr

使用自动识别语言Google

1
https://www.google.com/ncr

备份sources.list

1
2
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bk
sudo vim /etc/apt/sources.list
阅读全文 »

Java 中enum的书写方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public enum EnumColumn {
key1(valve1), key2(valve2), key3(valve2);

private String type;

EnumColumn(String type) {
this.type = type;
}

@Override
public String toString() {
return String.valueOf(this.type);
}
}

public static void main(String[] args) {

EnumColumn enumColumn1 = EnumColumn.valueOf(key1);
EnumColumn enumColumn2 = EnumColumn.key2;

System.out.println(groupColumn1.name());//key1
System.out.println(groupColumn1.toString());//valve1
System.out.println(groupColumn1.type);//valve1
}

如何利用序列化来完成对象的拷贝呢?在内存中通过字节流的拷贝是比较容易实现的。把母对象写入到一个字节流中, 再从字节流中将其读出来, 这样就可以创建一个新的对象了, 并且该新对象与母对象之间并不存在引用共享的问题, 真正实现对象的深拷贝。

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class CloneUtils {
@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(T obj){
T cloneObj = null;
try {
//写入字节流
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream obs = new ObjectOutputStream(out);
obs.writeObject(obj);
obs.close();
//分配内存, 写入原始对象, 生成新对象
ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream ois = new ObjectInputStream(ios);
//返回生成的新对象
cloneObj = (T) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
return cloneObj;
}
}
阅读全文 »

1
2
3
4
5
hexo n "title"  => hexo new "title"
hexo clean # 清除生成的public目录
hexo g => hexo generate #生成
hexo s => hexo server #启动服务预览
hexo d => hexo deploy #部署, 部署之前需要先 generate
0%