JAVA语言基础2
1. Java的内存划分和作用
Java内存模型(Java Memory Model,简称JMM)定义了Java虚拟机(JVM)在计算机内存(RAM)中的工作
方式。JMM是共享内存的并发模型,线程之间主要通过读-写共享变量(堆内存中的实例域,静态域和数组元
素)来完成隐式通信。JMM控制Java线程之间的通信,决定一个线程对共享变量的写入何时对另一个线程可
见。
JMM主要关注内存一致性和可见性两个问题。内存一致性是指在多线程环境下,多个线程同时访问内存中的数
据时,如何保证数据的一致性。可见性是指在一个线程修改了共享变量的值后,其他线程如何能够立即看到该
修改。
为了解决这些问题,JMM提供了以下同步机制:
1. 原子性:对于一些基本数据类型,如int、long等,JMM提供了原子操作,保证这些操作在多线程环境下
是原子性的,即不会被其他线程干扰。
2. 互斥性:使用synchronized关键字或ReentrantLock等同步机制,将代码块或方法声明为互斥的,保证同
一时间只有一个线程能够访问该代码块或方法,从而避免多个线程同时修改共享变量的问题。
3. 可见性:使用volatile关键字或synchronized关键字等同步机制,保证一个线程修改了共享变量的值后,
其他线程能够立即看到该修改。
JMM还定义了主内存和工作内存的概念。所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程
对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量。工作内存是JMM的一个抽象概
念,也叫本地内存,其存储了该线程以读/写共享变量的副本。
Java的内存划分主要分为以下几个部分:
1. 栈区(stack segment):由编译器自动分配释放,存放函数的参数值、局部变量的值等。其操作类似于
数据结构中的栈。
2. 堆区(heap segment):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它
与数据结构中的堆是两回事,分配方式倒是类似于链表。堆区是动态分配的内存区域,用于存放由new
创建的对象和数组。
3. 静态区(data segment):存放全局变量、静态变量和字符串常量,不释放。
4. 代码区(code segment):存放程序中方法的二进制代码,而且是多个对象共享一个代码空间区域。
此外,Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有
各自的用途,以及创建和销毁的时间。主要包括:
1. 程序计数器(Program Counter Register):线程私有,可以看做是当前线程所执行的字节码的行号指示
器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。
2. Java 虚拟机栈(Java Virtual Machine Stacks):线程私有,为虚拟机执行java方法服务。每一个方法在
执行的时候都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方
法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
3. Java 堆(Java Heap):线程共享,是java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享
的一块区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都
在这里分配内存。