西维蜀黍

【Java】枚举Enum

背景

Java语言中还没有引入枚举类型之前,表示枚举类型的常用模式是声明一组具有int常量。

  ...


【Java】枚举实现单例模式

背景

单例模式的不同实现

  ...


【Java】同步容器与线程安全问题

问题

对于线程安全的集合类(例如Vector)的任何操作是不是都能保证线程安全?

  ...


【Java】String - String.intern()方法

背景

String 类型拥有一个字符串常量池(String Constant Psool),使用字符串常量池包括以下两种方式:

  ...


【Java】垃圾回收 - 分代垃圾回收

为什么要分代?

分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的

因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率。

在Java程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关,比如Http请求中的Session对象、线程、Socket连接,这类对象跟业务直接挂钩,因此生命周期比较长。但是还有一些对象,主要是程序运行过程中生成的临时变量,这些对象生命周期会比较短,比如:String对象,由于其不变类的特性,系统会产生大量的这些对象,有些对象甚至只用一次即可回收。

试想,在不进行对象存活时间区分的情况下,每次垃圾回收都是对整个堆空间进行回收,花费时间相对会长。同时,因为每次回收都需要遍历所有存活对象,但实际上,对于生命周期长的对象而言,这种遍历是没有效果的,因为可能进行了很多次遍历,但是他们依旧存在。

因此,分代垃圾回收采用分治的思想,进行代的划分,把不同生命周期的对象放在不同代上,不同代上采用最适合它的垃圾回收方式进行回收。

如何分代?

如图所示,虚拟机中的共划分为三个代:新生代(Young Generation)老年代(Tenured Generation)持久代(Permanent Generation)。其中持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大。新生代和老年代的划分是对垃圾收集影响比较大的。

  ...


【Java】对象的内存分配 - 垃圾回收过程

对象的内存分配 - 垃圾回收过程

1 对象分配到新生代区域中

所有new出来的对象都会最先分配到新生代区域中,两个survivor区域初始化是为空的。

  ...


【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容器的实现原理。

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

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

  ...