2017-08-08 27 views
0

我有這樣的對象:傳遞給Java線程的對象是否佔用了堆外空間?

final List<Rows> rowsToSubmit = new ArrayList<>(rows); 

而且我實例線程在:

// submit to a thread 
executorService.submit(new Callable<Boolean>() { 
    @Override 
    public Boolean call() throws Exception { 
    Object threadObj = new Object(); 
    return bq.doHttpPost(rowsToSubmit); // takes about 3 seconds for IO 
    } 
}); 

確實Java的利用與rowsToSubmit對象的線程堆棧內存呢?換句話說,如果我的rowsToSubmit是巨大的,我是否需要增加我的堆外存儲器(我認爲Java線程堆棧位於那裏?)?

另外,threadObj是否也在堆外空間初始化?

回答

-1

Java通過訪問模式來使用堆棧內存,這使得從內存中分配和釋放內存變得微不足道(指針/整數只是遞增或遞減),而堆分配或釋放時涉及更復雜的簿記。

在Java中的每個線程都有自己的堆棧可使用-Xss JVM參數,同樣,你也可以使用JVM選項-Xms-Xmx其中-Xms指定Java程序的堆大小指定是堆的開始大小,-Xmx是java堆的最大大小。

+1

'threadObj'是一個引用,它存儲在堆棧中。它引用的對象在堆中。 – EJP

0

所有java對象都存儲在堆中,因此不需要配置堆外存儲器。

Java是一種傳遞引用語言,這意味着對象在方法或線程之間永遠不會重複。只有指針被傳遞,並且棧只保存了基元和指向對象的指針。例如,雖然一個指針rowsToSubmit對象存儲在線程堆棧上,對於rowsToSubmit對象的內容的存儲器仍存儲在堆上 - 存儲器被線程之間共享。

同樣,我也不會說threadObj是在離堆空間,因爲所有的Java對象都在堆初始化。對threadObj的引用存儲在堆外空間中。

延伸閱讀:http://www.journaldev.com/4098/java-heap-space-vs-stack-memory

+0

雖然這個陳述是正確的,但是我聲稱Java是「傳遞引用語言」,因爲「指針傳遞」是有點懷疑的。 Iirc Java本身正式將自己描述爲「按價值傳遞」 –

+0

_Reference按值傳遞._ –

0

Java Spec

每個Java虛擬機線程有一個專用的Java虛擬機棧,同時爲線程創建。 Java虛擬機堆棧存儲幀(第2.6節)。 Java虛擬機堆棧類似於傳統語言(如C語言)的堆棧:它包含局部變量和部分結果,並在方法調用和返回中扮演角色。由於除了推送和彈出框架之外,Java虛擬機堆棧從不直接操作,所以可能會分配堆棧。 Java虛擬機堆棧的內存不需要是連續的。

在Java虛擬機規範,第一版,Java虛擬機堆被稱爲Java堆棧。

該規範允許Java虛擬機棧要麼是固定大小的或所要求的計算動態擴展和收縮。如果Java虛擬機堆的大小是固定的,每一個Java虛擬機的堆的大小可以獨立地被創建堆棧時選擇的。

第二次當你通過參數傳遞一個對象時,它總是傳遞值。所以萬一它不會在堆中創建任何對象,只會將引用複製到局部變量,並且都會指向同一個對象。

相關問題