论 Java 中的内存分配

-------------------------------------------------------------------------java

Java内存分配主要包括如下几个区域:程序员

1. 寄存器:咱们在程序中没法控制安全

2. :存放基本类型的数据和对象的引用,但对象自己不存放在栈中,而是存放在堆中spa

3. :存放用new产生的数据线程

4. 静态域:存放在对象中用static定义的静态成员指针

5. 常量池:存放常量code

6. 非RAM(随机存取存储器)存储:硬盘等永久存储空间对象

 ------------------------------------------------------------------------------------blog

一. 寄存器(Registers):接口

     这是速度最快的存储场所,由于寄存器位于处理器内部,这一点和其余的存储媒介都不同。不过寄存器个数是有限的。

    在内存中的寄存器区域是由编译器根据须要来分配的。咱们程序开发人员不可以经过代码来控制这个寄存器的分配。

    因此说,这第一个存储区域寄存器,咱们只可以看看,而不可以对其产生任何的影响。,也没办法在程序里头感受到寄存器的任何存在迹象。

    JVM只设置了4个最为经常使用的寄存器。
  pc程序计数器
  optop操做数栈顶指针
  frame当前执行环境指针
  vars指向当前执行环境中第一个局部变量的指针
  全部寄存器均为32位。
  pc用于记录程序的执行。optop,frame和vars用于记录指向Java栈区的指针。

 

二. 栈(Stack):

 又称堆栈

   位于通常的RAM中。处理器经由指针提供直接支持。

   当程序配置一块新的内存时,stack指针便日后移;释放内存时,指针则往前移。

   这种方式不只很快,效率也高,速度仅次于寄存器。

   用于存放对象引用以及基本的数据类型对象,不能用于存储Java对象自己。


三. Heap):
   一种通用的内存空间,用来存放Java对象。

   Heap不一样于stack之处在于,编译器不需知道究竟得从heap中配置多少空间,也不需知道从heap上配置的空间究竟须要存在多久。

   所以,自heap配置存储空间能够得到高度的弹性。每当你须要产生对象,只需在程序中使用new,那么执行的时候,便会自heap配置空间。

   固然,你得为这样的弹性付出代价:从heap配置空间,比从stack配置,所耗费的时间多了很多。

 

 单论内存空间中的堆和栈:

   1.栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。Java自动管理栈和堆,程序员不能直接地设置栈或堆。

   2.优缺点:

      栈:

  栈的优点是,存取速度比堆要快,仅次于直接位于CPU中的寄存器

  但缺点是,存在栈中的数据大小与生存期必须是肯定的,缺少灵活性。另外,栈数据在多个线程或者多个栈之间是不能够共享的,可是在栈内部多个值相等的变量是能够指向一个地址的

      堆:

  堆的优点是能够动态地分配内存大小,生存期也没必要事先告诉编译器,Java的垃圾收集器会自动收走这些再也不使用的数据。

  但缺点是,因为要在运行时动态分配内存,存取速度较慢。

   3.栈有一个很重要的特殊性,就是存在栈中的数据能够共享

 

四. 静态域:

    静态存储区域就是指在固定的位置存放应用程序运行时一直存在的数据,Java在内存中专门划分了一个静态存储区域来管理一些特殊的数据变量如静态的数据变量,须要明确的一点就是,Java对象是不保存在这个地方的,而只是把对象中的一些特殊元素放置这。

    类变量也叫静态变量,也就是在变量前加了static 的变量;
    实例变量也叫对象变量,即没加static 的变量;
  区别在于:
     类变量和实例变量的区别在于:类变量是全部对象共有,其中一个对象将它值改变,其余对象获得的就是改变后的结果;而实例变量则属对象私有,某一个对象将其值改变,不影响其余对象;

  特色:

      这儿的“静态”(Static)是指“位于固定位置”(尽管也在RAM里)。程序运行期间,静态存储的数据将随时等候调用。可用static关键字指出一个对象的特定元素是静态的。但Java对象自己永远都不会置入静态存储空间
    例:

public class A{
    static int a = 0; //类变量
    private int b = 0; //实例变量
}

public class B{
    public void main (String[] args){
        A a1 = new A();
        A a2 = new A();
        a1.a = 3; // 等同于 A.a = 3;
        a1.b = 4 ;
        System.out.println(a2.a); //结果为3
        //类变量是针对全部对象的,因此a1改变a,a2的a也改变
        System.out.println(a2.b); //结果为0
        //实例只改变自身的,因此a1对象的b改变,不影响对象a2的b变量
    }
} 

   

五. 常量池:

  常量池在java用于保存在编译期已肯定的,已编译的class文件中的一份数据。它包括了关于类,方法,接口等中的常量,也包括字符串常量,如String s = "java"这种申明方式;固然也可扩充,执行器产生的常量也会放入常量池,故认为常量池是JVM的一块特殊的内存空间。

  背景:

    在Java对象中还有一类特殊的元素,咱们叫作常量。因为常量的值是稳定不变的,如圆周率。为此把他们放在代码的内部是可行的。

    不过有些时候,在进行一些嵌入式系统开发的时候,咱们每每不这么作。而是会把常量元素跟代码分开来保存。

    如咱们会根据状况把常量的值存放在一些只读存储器中。这主要是为了一些特殊的功能考虑的。

    如出于版权控制的须要。如在打印机上为了保护原装耗材的版权,每每把常量跟代码分开存放

特色:

    在Java程序中,有不少的东西是永恒的,不会在运行过程当中变化。

          好比一个类的名字,一个类字段的名字/所属类型,一个类方法的名字/返回类型/参数名与所属类型,一个常量,还有在程序中出现的大量的字面值。

   常数值一般直接置于程序代码内部。这样作是安全的,由于它们永远都不会改变。有的常数须要严格地保护,因此可考虑将它们置入只读存储器(ROM)。

 

六.  非RAM存储:

  若数据彻底独立于一个程序以外,则程序不运行时仍可存在,并在程序的控制范围以外。其中两个最主要的例子即是“流式对象”和“固定对象”。对于流式对象,对象会变成字节流,一般会发给另外一台机器。而对于固定对象,对象保存在磁盘中。

  即便程序停止运行,它们仍可保持本身的状态不变。对于这些类型的数据存储,一个特别有用的技巧就是它们能存在于其余媒体中。一旦须要,甚至能将它们恢复成普通的、基于RAM的对象

   背景:  

  有时候,有些程序运行所须要的数据咱们还会放置在其余地方。如在一些系统中须要用到流对象,这个对象的数据并无保存在上面所谈到的任何一个存储区域,这个对象直接被转为为字节流,发送到其余的主机上去了。另外有一种叫作持久化的对象,其是被存储在硬盘中的

 

七. 论各种型内存的执行速度:

  寄存器 > 堆栈 > 堆 > 其余

 

 

(C) 房上的猫 。 保留全部权利。
 https://www.cnblogs.com/lsy131479/

如需转载,请注明出处!!!

相关文章
相关标签/搜索