Java内存分配浅析

[TOC]

Java内存分配浅析

计算机存储结构

先来简单了解下计算机的存储结构,计算机采用三级存储结构:

  • 高速缓冲存储器cache
  • 主存储器
  • 辅存储器

可看做两层:cache-主存,主存-辅存
细分的存储层次:

  • CPU(寄存器)
  • cache
  • 内存(RAM)
  • 硬盘(Hard Disk)

    java数据类型

    基本类型

    8bit = 1Byte
  • byte, 8bit
  • int, 32bit
  • short, 16bit
  • long, 64bit
  • boolean, 16bit
  • float, 32bit
  • double, 64bit
  • char, 16bit

    引用类型

    Array, String和对象,都位于堆中。

基本类型变量只在栈区占用一块内存,而引用类型变量要在栈区和堆区各占一块内存。

Java内存区域

java程序的运行在JVM中,运行时虚拟机会将它所管理的内存区域划分为若干不同的数据区域,这些区域都有各自的用途及创建销毁时间。

就速度来说,有如下关系:
寄存器 < 栈 < 堆 < 其他

寄存器(Register)

CPU内部元件,每个寄存器都有自己的名字,程序无法直接控制,高速读写速度。分为内部寄存器和外部寄存器。
内部寄存器也就是小小的存储单元。
可用来寻址或者计算

栈,堆

java将内存(RAM)分为栈内存和堆内存

栈(Stack)

存放基本类型的数据(如int,short,long,byte,boolean,float,double,char…)和引用类型的地址。引用类型本身存放在堆中。

当程序中定义一个变量时,就在栈中为变量分配一个内存空间,当变量超出作用域时,java会自动释放改变量的内存空间。

创建程序时候,JAVA编译器必须知道存储在堆栈内所有数据的确切大小和生命周期,因为它必须生成相应的代码,以便上下移动堆栈指针。这一约束限制了程序的灵活性

堆(Heap)

存放由new创建的数组和对象,有java虚拟机的垃圾回收机制自动回收。当堆中的数组和对象在没有引用变量指向它们的时候,才会变为垃圾,然后在随后一个不确定的时间被回收,这也是java比较占内存的原因。

运行时数据区,运行过程中动态分配内存的。

java堆是所有线程所共享的一块内存区域,该区域的唯一目就是存放对象。可以处于物理上不连续的空间,逻辑上连续即可
java中的指针:栈中的引用变量指向堆中的变量

区别

栈:存取速度快,仅次于寄存器,栈数据可以共享。存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
堆:运行时动态分配,存取速度慢。

String类型存放

字符串是一个特殊包装类,其引用是存放在栈里的,而对象内容必须根据创建方式不同定(常量池和堆).有的是编译期就已经创建好,存放在字符串常 量池中,而有的是运行时才被创建.使用new关键字,存放在堆中。
详细内容请查看String解析一文

静态域(static storageb)

这里的“静态”是指“在固定的位置”。静态存储里存放程序运行时一直存在的数据。你可用关键字static来标识一个对象的特定元素是静态的。

常量池(constant pool)

常量池指在编译期被确定,并保存在已编译的.class文件中的一些数据,包括定义的基本常量数据,对象型(String及数组)和常量值(final)。
JVM必须为每个装载的类型维护一个常量池,常量池就是该类型所用到的常量的义序有序集合
在堆中分配出来的一块存储区域,存放储显式的String常量和基本类型常量(float、int等)。另外,可以存储不经常改变的东西(public static final)。常量池中的数据可以共享。

非RAM存储

硬盘等永久存储空间,存放一些数据完全存活于程序之外,它可以不受程序的任何控制,在程序没有运行时也可以存在。

堆栈溢出

  1. 堆溢出简单,循环创建对象即可

    for(;;){
        ArrayList list = new ArrayList(2000);
    }
    
  2. 栈溢出
    实现栈溢出,需要调用递归

    public void test(){
        this.test();
    }
    
  3. JVM堆栈设置

    java –Xms128m //JVM占用最小内存
        –Xmx512m //JVM占用最大内存
        –XX:PermSize=64m //最小堆大小
        –XX:MaxPermSize=128m //最大堆大小
    

参考:
Java 内存分配全面浅析
深入Java核心 Java内存分配原理精讲
深入理解Java的栈与堆栈

文章目录
  1. 1. Java内存分配浅析
    1. 1.1. 计算机存储结构
    2. 1.2. java数据类型
      1. 1.2.1. 基本类型
      2. 1.2.2. 引用类型
    3. 1.3. Java内存区域
      1. 1.3.1. 寄存器(Register)
      2. 1.3.2. 栈,堆
        1. 1.3.2.1. 栈(Stack)
        2. 1.3.2.2. 堆(Heap)
        3. 1.3.2.3. 区别
        4. 1.3.2.4. String类型存放
      3. 1.3.3. 静态域(static storageb)
      4. 1.3.4. 常量池(constant pool)
      5. 1.3.5. 非RAM存储
    4. 1.4. 堆栈溢出