`
关西平次君
  • 浏览: 4391 次
  • 性别: Icon_minigender_1
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

Java中的堆内存、栈内存和方法区总结

    博客分类:
  • Java
阅读更多

    Java中内存分成两种,一种叫做栈内存,一种叫做堆内存。还有一个方法区,也叫做静态区。
1.栈内存中放哪些东西?
 ①基本类型的变量,例如int a=3中的a;
 ②对象的引用变量,例如Thread t=new Thread();中的t。
      当在代码块中定义一个变量时,Java就在栈中为这个变量分配内存空间;当超过变量的作用域后,Java会自动 释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。

2.堆内存中存放哪些东西?
 ① 存放由new创建的对象和数组。
     在堆中存放的内存,由Java虚拟机垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量持有的内容等于数组或者对象在堆内存中的首地址。在栈中的这个特殊的变量,就成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。
 
3.静态区/方法区:
    方法区(method)也叫做静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
    方法区中包含的都是在整个程序中永远唯一的元素,例如class,static变量。
    全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量放在相邻的另一块区域。
 
堆内存和栈内存,两者的区别? 
 ①引用变量是普通变量,定义时在栈内存中分配,引用变量在程序运行到作用域外后被释放。而数组和对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在的代码块之外,数组和对象本身占用的堆内存也不会被释放。数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉,这个也是Java比较占内存的主要原因。实际上,栈中的引用变量指向堆内存中的变量,这就是Java中的指针。
 
 ②通俗来讲,堆是用来存放对象的,而栈是用来执行程序的。
 ③jvm只有一个堆区(heap),被所有线程共享;
 每个线程包含一个栈区(stack),每个栈中的数据都是私有的,其他的栈不能访问,但是同一个栈中变量是共享的;分为3个部分:基本类型变量区,执行环境上下文,操作指令区。
 
 

为什么要有堆和栈?这样设计有什么好处?
 ①Java自动管理堆和栈,程序员不能直接地设置栈和堆。
 ②Java的堆是一个运行时数据区。堆是由JVM的垃圾回收器自动管理的。堆的优势是可以在程序运行时,动态地分配内存
 大小,但是正是由于这个原因,它的存取速度较慢。
 ③栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小和生存期是必须确定的,缺乏灵活性。
     栈有一个很重要的特性,就是存在栈中的数据可以共享。假设我们同时定义:

  int a = 3;

  int b = 3;

    编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。要注意这种数据的共享与两个对象的引用时
指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。

分享到:
评论

相关推荐

    Java中堆内存与栈内存分配浅析

    本文将深入探讨Java中堆内存与栈内存的分配机制,并通过对比分析它们之间的差异,帮助读者更好地掌握Java内存管理的核心概念。 #### 二、堆内存与栈内存概述 ##### 1. 堆内存 堆内存是Java虚拟机(JVM)用于存储...

    Java中堆内存和栈内存详解

    这段代码首先在栈内存中创建了一个引用变量`x`,然后在堆内存中创建了一个包含100个整数元素的数组,并将该数组的地址赋值给`x`。因此,`x`实际上是指向堆内存中数组的引用。 **引用变量的特点:** - 引用变量本身...

    java 内存中 堆、栈、常量池、方法区的总结

    在Java内存管理中,堆(Heap)、栈(Stack)、常量池(Constant Pool)和方法区(Method Area)是四个核心概念,它们在Java程序运行时扮演着不同的角色。 首先,方法区是用来存放类的信息、常量、静态变量等数据的...

    Java中栈内存和堆内存详解

    Java中栈内存和堆内存详解,非常容易理解

    Java中的堆和栈

    - **作用域限定**:栈内存中的变量在其定义的方法结束时就会被销毁,因此它的生命周期非常明确。 - **快速分配和释放**:栈内存的分配和释放速度快,因为它是基于线程的,随着方法的调用和退出自动完成。 - **数据...

    Java中堆内存和栈内存详解.doc

    `p1`和`p2`作为引用变量被存储在栈内存中,而Person对象本身则位于堆内存中。当`shout()`方法被调用时,它的局部变量(如果有的话)将在栈内存中分配。 #### 五、内存分配策略 在Java中,内存分配遵循以下几种原则...

    Java中堆与栈的内存分配.pdf

    Java中的内存分配策略有三种:静态存储分配、栈式存储分配和堆式存储分配。静态存储分配是在编译时就能确定每个数据目标在运行时刻的存储空间需求的。栈式存储分配是由一个类似于堆栈的运行栈来实现的,程序对数据区...

    Java 中的堆和栈

    栈内存中的数据可以共享,比如在创建多个相同值的基础类型变量或引用相同对象时,Java可能会复用已存在的值或引用,而不是每次都创建新的。例如,`int a = 3; int b = 3;` 在这种情况下,a和b都指向栈中同一个3的值...

    Java中堆内存和栈内存详解文.pdf

    Java编程语言将内存划分为两种主要区域:栈内存和堆内存。栈内存主要用来存储基本类型(如int、char)的变量和对象的引用,而堆内存则用于存储通过`new`关键字创建的对象和数组。 栈内存的工作方式类似于数据结构中...

    Java中堆和栈的区别

    以下代码片段展示了如何在Java中使用栈和堆内存: ```java String a = "abc"; String b = "abc"; String c = new String("abc"); System.out.println(a == b); // true System.out.println(a.equals(b)); // true ...

    区别Java中堆与栈区别Java中堆与栈

    在 Java 中,栈和堆都是自动管理的,程序员不能直接地设置栈或堆。Java 的垃圾收集器会自动收走这些不再使用的数据。 栈有一个很重要的特殊性,就是存在栈中的数据可以共享。例如,int a = 3; 和 int b = 3;,它们...

    Java堆、栈和常量池——内存剖析

    - 堆内存中的对象生命周期不确定,由垃圾回收机制自动管理。 - 堆中的对象可以是任何类型,包括自定义类的对象。 - 对于`new`创建的对象,其生命周期和大小都不需要预先确定,这为程序提供了极大的灵活性。 ####...

    内存中堆和栈的区别

    内存中堆和栈的区别 内存中堆和栈是两个不同的概念,都是用来存放数据的内存区域,但它们有所区别。 内存分配方面 堆:一般由程序员分配释放,若程序员不释放,程序结束时可能由 OS 回收。堆的分配方式类似于链表...

    详解java堆和栈

    通过对Java中堆和栈的介绍及示例分析,我们可以看到两者在Java程序中的重要作用。掌握这些基础知识有助于更好地理解和优化程序的性能。 在实际开发过程中,合理利用堆和栈的特点能够有效提升程序的运行效率和资源...

    内存中的堆与栈区别 内存中的堆与栈区别

    在程序中,内存分为四块,其中有一块用于存放代码,这里我们不讨论,这四块分别是:全局区(静态区)、文字常量区、栈区和堆区。 全局区(静态区) 全局变量和静态变量都存储在这块区域,与其他变量的明显区别就是...

Global site tag (gtag.js) - Google Analytics