安全点是什么?为什么有人会写Thread.sleep(0)这样的代码?Thread.sleep(0)的作用是什么?

安全点是什么?为什么有人会写Thread.sleep(0)这样的代码?Thread.sleep(0)的作用是什么?

先看下面的代码实例:

for(int i = 0 , int j = 0; i < this.fileSize; i += DefaultMappedFile.OS_PAGE_SIZE, j++) {
	// 略逻辑代码

	if(j % 1000 == 0){
		// 略部分代码
		try{
			Thread.sleep(0);  //为什么这里要执行这样看似无意义的事情?
		} catch(InterruptedException e){}
	}
}

直接说答案:上面的Thread.sleep(0);是为了让触发GC垃圾回收

那为什么Thread.sleep(0);就可以触发GC垃圾回收那?Java不是有自动的垃圾回收机制吗?为什么这里需要像C、C++那样自己去管理内存那?

这里我们需要提到一个新的概念Safepoint 安全点; 安全点的设定决定了用户程序执行时并非在代码指令流的任意位置都能够停顿下来开始垃圾收集,而是强制要求必须执行到达安全点后才能够暂停。

简单理解上面的话就是:在用户程序执行到安全点之前,是不能进入STW(Stop-The-World)状态的,也就不能够进行GC。

STW是什么:简单来说就是暂停除GC线程外的所有线程,好进行垃圾回收。在GC线程执行完后,其它线程恢复执行。

那安全点是怎么设置的那?
方法调用,异常跳转,循环跳转等都会产生安全点。

可能会有人有个疑问:那安全点要是过多,那GC垃圾回收岂不是会很频繁?

看下面这段描述:HotSpot虚拟机为了避免安全点过多带来过重的负担,对循环还有一项优化措施,认为循环次数较少的话,执行时间应该也不会太长,所以使用int类型或范围更小的数据类型作为索引值的循环默认是不会被放置安全点的。这种循环被称为可数循环,相对应地,使用long或者范围更大的数据类型作为索引值的循环被称为不可数循环,将会被放置安全点。

那看到上面的解释,其实也就能大概猜出来Thread.sleep(0);的作用就是放置一个安全点,那为什么它就可以放置安全点那?

因为在源码中就规定了,native方法就是要放置安全点的,而sleep就是一个native

private static native void sleep() throws //略{
	// 略
}

你可能感兴趣的:(jvm,java,开发语言,安全点)