什么是棧上分配
棧上分配是java虛擬機(jī)提供的一種優(yōu)化技術(shù),基本思想是對(duì)于那些線程私有的對(duì)象(指的是不可能被其他線程訪問(wèn)的對(duì)象),可以將它們打散分配在棧上,而不是分配在堆上。分配在棧上的好處是可以在函數(shù)調(diào)用結(jié)束后自行銷毀,而不需要垃圾回收器的介入,從而提供系統(tǒng)的性能。
棧上分配的一個(gè)技術(shù)基礎(chǔ)是進(jìn)行逃逸分析。逃逸分析的目的是判斷對(duì)象的作用域是否有可能逃逸出函數(shù)體。
下面的代碼顯示了一個(gè)逃逸的對(duì)象:
public class PartionOnStack {
static class User{
private int id;
private String name;
public User(){}
}
private static User user;
public static void foo() {
user=new User();
user.id=1;
user.name="sixtrees";
}
public static void main(String[] args) {
foo();
}
}
因?yàn)樯厦娴拇a中的User的作用域是整個(gè)Main Class,所以u(píng)ser對(duì)象是可以逃逸出函數(shù)體的。下面的代碼展示的則是一個(gè)不能逃逸的代碼段。
public class PartionOnStack {
class User{
private int id;
private String name;
public User(){}
}
public void foo() {
User user=new User();
user.id=1;
user.name="sixtrees";
}
public static void main(String[] args) {
PartionOnStack pos=new PartionOnStack();
pos.foo();
}
}
代碼來(lái)幫忙:
通過(guò)上面的分析,我們知道java虛擬機(jī)會(huì)幫助我們?cè)跅I线M(jìn)行分配,我們?cè)O(shè)置了1億次alloc的對(duì)象創(chuàng)建,每個(gè)User對(duì)象實(shí)例需要占用16字節(jié)的空間,如果沒(méi)有優(yōu)化,累計(jì)的空間申請(qǐng)將有1.5GB這么大,如果我們的堆空間設(shè)置的值小于1.5GB的話,就會(huì)發(fā)生GC。代碼如下:
public class PartionOnStack {
class User{
public int id;
public String name;
}
public void foo() {
User user=new User();
user.id=1;
user.name="sixtrees";
}
public static void main(String[] args) {
System.out.println("start-----------");
long beginTime=System.currentTimeMillis();
PartionOnStack pos=new PartionOnStack();
for(int i=0;i<100000000;i++)
{
pos.foo();
}
long endTime=System.currentTimeMillis();
System.out.println("總共運(yùn)行----"+(endTime-beginTime)+"ms");
}
}
使用下面的參數(shù)運(yùn)行上面的代碼
-server -XMX10m -Xms10m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:-UseTLAB -XX:+EliminateAllocations
對(duì)于大量的零散小對(duì)象,棧上分配提供了一種很好的對(duì)象分配策略,棧上分配的速度快,并且可以有效地避免垃圾回收帶來(lái)的負(fù)面的影響,但由于和堆空間相比,??臻g比較小,因此對(duì)于大對(duì)象無(wú)法也不適合在棧上進(jìn)行分配。