摘要:
1堆栈:自动为编译器分配和释放,例如函数参数,局部变量,临时变量等。
2堆:为成员分配和释放,由程序员自己申请和释放。否则,会发生内存泄漏。通常,用于新应用程序的堆的内容。
除了这两部分,还有另一部分:
3静态存储区:编译程序时分配了内存,并且该内存在程序的整个运行期间都存在。它主要存储静态数据,全局数据和常量。
Java堆内存
在Java运行时期间,堆内存用于为对象和JRE类分配内存。每当我们创建对象时,它将始终在堆内存中创建。垃圾回收在堆内存上运行,以释放未被引用的对象占用的内存。在堆上创建的任何对象都具有全局访问权限,并且可以在应用程序中的任何位置引用。
Java堆栈内存

Java的堆栈内存用于线程执行。它们包含生命周期短的特定值方法,并在堆中使用该方法引用对象。堆栈存储器是LIFO(后进先出)序列。调用该方法时,会在堆内存中创建一个新块,以保存本地原始值以及对该方法中其他对象的引用。该方法结束后,该块可用于其他方法。与堆内存相比,栈内存非常小。
我们使用以下示例了解堆内存和堆栈内存
[java]
packagecom.journaldev.test; publicclassMemory {publicstaticvoidmain(String [] args){// Line1inti = 1; // Line2Objectobj = newObject(); // Line3Memorymem = newMemory(); // Line4mem.foo(obj); // Line5} // Line9privatevoidfoo(Objectparam){// Line6Stringstr = param.toString(); //// Line7System.out.println(str);} // Line8}
下面的图片显示了上面程序堆和堆栈内存的引用,以及它们如何用于存储对原始值,对象和变量的引用。

让我们看一下程序执行的过程:
1、一旦运行此程序,它将把所有正在运行的类加载到堆内存中。在第一行中找到main()方法后,Java将创建一个可由main()方法堆栈内存使用的线程。

2、在第一行中,我们创建一个本地基本变量,该变量将创建并保存在main()堆栈中。
3、因为我们在第三行中创建了对象,所以将在堆内存中创建该对象,并将其引用保存在堆栈内存中。当我们在第四行中创建Memory对象时,也会发生相同的过程。
4、当我们在第五行中调用foo()方法时,将在堆顶部创建一个块,以供foo()方法使用,因为Java是通过值传递的,并且是一个新对象在第六行中的引用是在foo()方法中的堆栈中创建的
5、在第七行创建一个String,它在堆空间的String池中运行,并且它的引用也在foo()方法的堆栈空间中创建
6、 foo()方法在第八行结束,这时可以释放为堆中的foo()方法分配的内存块
7、在第9行中,main()方法结束,并且可以破坏堆栈为main()方法创建的存储空间。该程序也同时结束,Java释放所有内存并结束该程序的运行
堆内存和堆栈内存之间的区别
基于以上解释,我们可以轻松地总结堆与栈之间的区别:

1、应用程序的所有部分都使用堆内存,然后通过运行线程来使用堆栈内存。
2、每当创建对象时,它将存储在堆存储器中,并且堆栈存储器包含其引用。堆栈存储器仅包含对堆中原始值变量和对象变量的引用。
3、堆中存储的对象是全局可访问的,但是其他线程无法访问堆栈内存。
4、堆栈中的内存管理是使用LIFO完成的,并且堆内存的管理更为复杂,因为它是全局访问的。堆内存分为年轻一代,老一代等等。
5、堆栈存储器的生命周期很短,但是堆存储器的生命周期是从程序的开始到结束。
6、我们可以使用-Xms和-Xmx JVM选项来定义起始大小和最大堆内存,并且可以使用-Xss来定义堆栈大小
7、当堆栈内存已满时,Java会引发java.lang.StackOverFlowError,而当堆栈内存已满时,Java会引发java.lang.OutOfMemoryError:Java堆空间错误
8、与堆内存相比,由于显式使用了内存分配规则(LIFO),因此与堆内存相比,堆栈内存要小得多。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shoujiruanjian/article-362690-1.html
故以老旧舰试探
如果我们不趁机加强南海诸岛的军事存在
别随便说同志不合法