一 java内存结构
Heap(堆)实例分配的地方通过Xms与Xmx来设置
MethodArea(方法区域)类的信息及静态变量 对应是Permanet Generation 通过XXPermSize来设置
JavaStack(java的栈)虚拟机只会直接对Javastack执行两种操作以帧为单位的压栈或出栈通过Xss来设置 若不够会抛出StackOverflowError
ProgramCounter(程序计数器)每一个线程都有它自己的PC寄存器也是该线程启动时创建的PC寄存器的内容总是指向下一条将被执行指令的饿地址这里的地址可以是一个本地指针也可以是在方法区中相对应于该方法起始指令的偏移量
Nativemethodstack(本地方法栈)保存native方法进入区域的地址
当中Heap和MethodArea是被所有线程的共享使用的
而JavastackProgramcounter和Nativemethodstack是以线程为粒度的每个线程独自拥有自己的部分
二 内存模型
由以上可以知道java内存分为main memory和线程的Working Memory就会涉及到这两种内存数据同步以及多个线程操作时数据一致性和可见性的问题这就不可避免要加锁了在java中可采用如下的形式
synchronized关键字或使用ncurrentlocks中的锁
volatile关键字 Volatile表示的是线程每次操作都是在主内存中进行 这只能保证其可见性 而不能保证其的原子性 要有原子性还得加锁
final变量(基本类型类类型还是可以改值的)
三 如何保证线程安全
每个线程只操作自有的数据 这个可能性要小
设计的类无数据成员 也就没有共享变量 要有可用是 final或volatile
在操作共享变量时同步