Java中 棧記憶體的訪問速度僅次於暫存器,如何做到的?

時間 2021-05-05 17:55:02

1樓:Ivony

嚴格的來說,這句話把棧(堆疊)和暫存器相提並論原則上就錯了。

這兩者完全不對等,沒有可比性。棧(堆疊)的對等的概念是堆,託管堆。

說白了,我們說這個變數在棧上,實際上這個變數說不定已經到了暫存器裡面了。那怎麼比較什麼所謂的棧和暫存器的訪問速度呢?

2樓:劉梓牧

因為有空間區域性性(locality)棧的訪問不像堆一樣那麼隨意,而是在變化不大的一部分空間內訪問,在訪問資料的時候一整塊的資料都會被載入進快取,就是那個L1.所以棧的miss率很小啊,所以就接近SDRAM

的訪問速率了。

3樓:楊培文

反正我這裡棧比堆快

#include

#include

using

namespace

std;

#define SIZE 10*1024

intmain

()gettimeofday(&

end,

NULL

);delta

=1000000*(

end.

tv_sec

-start

.tv_sec)+

end.

tv_usec

-start

.tv_usec

;cout

<<"賦值使用了"

<

<<"微秒"

<

;cout

<<"棧:"

<

;gettimeofday(&

start

,NULL

);int

test2

[SIZE

];gettimeofday(&

end,

NULL

);delta

=1000000*(

end.

tv_sec

-start

.tv_sec)+

end.

tv_usec

-start

.tv_usec

;cout

<<"分配使用了"

<

<<"微秒"

<

;gettimeofday(&

start

,NULL

);for

(intj=

0;j<

SIZE;j

++)for(

inti=0

;i

++)gettimeofday(&

end,

NULL

);delta

=1000000*(

end.

tv_sec

-start

.tv_sec)+

end.

tv_usec

-start

.tv_usec

;cout

<<"賦值使用了"

<

<<"微秒"

<

;return0;

}結果如下:

堆:分配使用了5微秒賦值使用了310422微秒棧:

分配使用了0微秒賦值使用了267218微秒

4樓:auxten

會快一點兒,以x86為例,分配記憶體:

棧記憶體,就是乙個操作ESP暫存器的CPU指令。

堆記憶體,呼叫malloc/calloc,還可能會呼叫核心的brk、sbrk、mmap。

使用:棧記憶體,由於函式呼叫引數、返回值的頻繁使用,幾乎一直可以在L1、L2、L3 cache中命中。

堆記憶體,range太大,除非連續訪問,否則很難命中。

5樓:

而且,jvm中的棧和彙編的棧根本不是一回事,jvm中也沒暫存器的事。也許你區域性變數少,jvm解釋成彙編之後一優化就全存進暫存器了呢?

6樓:

Talk is cheap, show me the code.

// compile with: g++ -std=c++0x -O2 -Wall -g -o "foo.cc" "foo"

#include

#include

#include

#include

#include

using

namespace

std;

#define print(x) cout << x << endl#define input(x) cin >> x#if defined(__i386__)static

__inline__

unsigned

long

long

rdtsc

(void

)#elif defined(__x86_64__)static

__inline__

unsigned

long

long

rdtsc

(void

)#endif

//#define MEMORY_ON_HEAP//#define MEMORY_ON_STACKconst

intSIZE

=102400

;int

*array

[SIZE]=

;int

main

()#endif

#ifdef MEMORY_ON_STACK// RDSTC: 3660502

for(

inti=0

;i

++)#endif

unsigned

long

long

end=

rdtsc

();print

(end

-start

);return0;

}"alloca" vs "placement new"

7樓:

前兩天才剛看到另乙個問題也是關於所謂的「棧記憶體比堆記憶體快」的偽問題

說真的,我不知道這個謬論是怎麼產生,又怎麼傳播開的。

如果說是對比棧上的區域性變數和堆上的變數,那堆上的變數可能多了一次間接定址的過程。但是,這並不是因為堆或者棧的原因---而是因為指標本身的特性。如果你拿乙個指標指向乙個棧的變數,一樣會產生這樣的效果(如果編譯器沒有識別出來並且優化掉的話)。

所以,唯一產生可能棧比堆快的因素,大概就是在編譯時,如果編譯器能識別出所指向的變數位於棧上,可能會把指標的間接定址過程優化為ebp減去乙個即時數的過程,這樣,就把記憶體定址變為了暫存器取數,是會快一些。

另外,棧的資料也可能有利於cpu的cache,減少cache miss?這點我不確定,僅僅是覺得有可能。

所以,一般來說,沒理由認為棧記憶體要比堆記憶體快。

8樓:趙劼

答案就是棧和堆都是記憶體,棧不比堆快,都是記憶體訪問,只是訪問方式上不同(導致區域性性好容易在CPU快取裡)。

吐槽時間到:果然好多人傳著傳著原因都沒了只記得結論了,最後人人都記得棧的速度比堆塊,然後還覺得自己好懂底層,簡直跟擼完覺得自己性生活滿足一樣。

java棧記憶體溢位怎麼產生?

咖啡旅行記 intlevel 1 static void callback 要outOfMemory static ArrayList list new ArrayList static void callback 夠直觀明了了吧?大家來贊我一下。 單執行緒下,xss設定太小,或者定義太多的本地變數...

java的String在記憶體中如何分配的?

陳肖恩 1.myString 是常量,通過編譯期直接定義到常量表中,new String 是執行期指令,基本上new出來的物件都在堆上。可以理解為編譯期常量表定義了 myString 字串,在執行期調取常量new出乙個String物件放到堆裡,兩者引用不一樣。2.字面量字串可以在編譯器優化,例如常量...

java的基本型別的成員變數在棧還是堆?

Intopass 區域性變數在stack中,包括基本型別變數和引用。成員變數在heap中,包括基本型別變數和引用。引用中儲存的是指向head的位址。說到引用型別時,要把引用自身和heap中的物件區分開來。你完全可以宣告乙個引用賦值為null,那麼就不指向heap中的物件了。 愛諳夜令 先說結論,放在...