西维蜀黍

【Java】垃圾收集(Garbage Collection)

背景

程序计数器、虚拟机栈和本地方法栈3个区域随线程而生,随线程而灭。

栈中的栈帧随着方法的进入和推出,而进行着出栈和进栈操作。每一个栈帧中分配多少内存基本上是在类结构确定下来就已知的。

因此这几个区域的内存分配和回收都具有确定性,在方法结束或线程结束时,内存就跟随着回收了。

而Java堆和方法区则不一样,一个接口的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样,只有在程序处于运行期间,才知道创建哪些对象,这部分内存的分配和回收都是动态的,垃圾收集器关注的就是这部分内存。


对于从事C和C++程序开发的开发人员来说,在内存管理领域,他们既是拥有最高权利的皇帝,也是从事最基础工作的劳动人民—–既拥有每一个对象的所有权,又担负着每一个对象从生命开始到终结的维护责任。 对于Java程序员来说,虚拟机的自动内存分配机制的帮助下,不再需要为每一个new操作去写配对的delete/free代码,而且不容易出现内存泄露和内存溢出问题,看起来由虚拟机管理内存一切都很美好。不过,也正是因为Java程序员把内存控制的权利交给Java虚拟机,一旦出现内存泄露和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那排查错误将会是一项异常艰难的工作。

判断对象已死 - 哪些内存需要回收

堆中几乎存放着Java世界中所有的对象实例,垃圾收集器在对堆回收之前,第一件事情就是要确定这些对象哪些还“存活”着,哪些对象已经“死去”(即不可能再被任何途径使用的对象)。

  ...


【Java】关键字 - final

final 的简介

final可以修饰变量,方法和类,用于表示所修饰的内容一旦赋值之后就不会再被改变,比如String类就是一个final类型的类。

  ...


【Java】集合类 - 并发容器(Concurrent Container)

背景

java.util.concurrent包下面为我们提供了丰富的类和接口供我们开发出支持高并发、线程安全的程序。

  • 同步容器类:Vector,HashTable和Collections.SynchronizedXXX()
  • 并发容器类:包括ConcurrentHashMap,CopyOnWrite容器以及阻塞队列。
  ...


【Java】集合类 - List - CopyOnWriteArrayList

背景

CopyOnWriteArrayList容器是Collections.synchronizedList(List list)的替代方案。

CopyOnWriteArrayList在某些情况下具有更好的性能(读操作远多于写操作时)。在传统的使用 synchronized 关键字以保证互斥操作的实现中(比如 Vector),通常会把读操作进行加锁,因而任一时刻只能有一个读线程能够获得锁,所以其他的读线程都必须等待,大大影响性能。

CopyOnWriteArrayList称为“写时复制”容器,就是在多线程对容器对象进行读写操作时,执行写操作的线程在写的同时,还会把容器复制一份(并对复制后的容器实例进行写修改操作),最终就可以做到写操作进行的同时,不阻塞其他线程的读操作。

从JDK1.5开始Java并发包里提供了两个使用CopyOnWrite机制实现的并发容器,它们是CopyOnWriteArrayList和CopyOnWriteArraySet。

CopyOnWriteArrayList

CopyOnWriteArrayList实现

先说说CopyOnWriteArrayList容器的实现原理。

简单地说,就是在需要对容器进行操作的时候,将容器拷贝一份,对容器的修改操作都在容器的拷贝副本中进行。当修改操作结束,再用容器的拷贝副本替换掉原来的容器。

这样设计的好处是实现了读写分离,并且读读时不会发生阻塞。

  ...


【Java】hashCode()

背景

哈希表(Hash Table)这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到哈希表(Hash Table)来提高查找效率。在Java的Object类中有一个方法:

public native int hashCode();

根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现。

为何Object类需要这样一个方法?它有什么作用呢?今天我们就来具体探讨一下hashCode方法。

  ...