您的位置:首页 > 编程语言 > Java开发

JVM:Java内存区域和Java内存模型

2018-03-12 15:56 218 查看
第二遍看《深入理解Java虚拟机》了,代码的沉淀确实能对技术和理解带来一定影响。第一遍读这本书的时候感觉能看懂,但是抓不住重点,关键就记了下以下的概念:
    1.Java的内存区域。
    2.判断对象是否可被回收。
    3.垃圾回收算法。
    4.类加载机制、双亲委派模型。
    5.静态分派和动态分派(实现多态的)。
    6.多线程相关,volatile之类的。
这次看理解是更深刻一点了,记录下。(不过虽然经典知识一般都是不变的,但是技术不断在更新,新技术需要不断去学,这里仅做一个记录)。
Java内存区域:
看到张好图,引用下。



通过这张图,大概就知道JVM的内存区域分布了。
其实简单来讲,JVM内存分为GC堆和其他区域,但是详细来讲,JVM分为堆、方法区、虚拟机栈、本地方法栈、程序计数器。
1.方法区存储类的信息、常量、静态变量等。GCLib、OSGi等技术会创建很多类,为了防止OOM,这些技术需要提供类卸载的功能。(OSGi破坏了双亲委派模型,因为用户追求程序的动态性,OSGi成了实际上Java模块化的标准,把类加载器从双亲委派模型形成的树状结构发展成了网状结构)
2.方法区一般不GC,回收目标主要针对常量池的回收和对类型的卸载。
Java内存模型:

主要分为主内存和
Java内存模型主要目标是定义程序中各个变量的访问规则(所有的变量存储在主内存,每条线程有自己的工作内存)。
原子性:Java内存模型来保证原子性的变量操作
                    -> 基本数据类型的访问读写具备原子性。
可见性:一个变量修改了共享变量的值,其他线程能够立即的值这个修改。
                    -> 通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值这种依赖主内存作为传递媒介的方式来实现可见性。
有序性:本线程内观察,所有操作都是有序的(线程内表现为串行),如果在一个线程中观察另一个线程,所有操作都是无序的("指令重排序"和"工作内存和主内存同步延迟")。
1.volatile:

使变量具有可见性
禁止指令重排序优化
出于这个,所有volatile不能保证多线程进行i++操作得到想要的值,volatile只保证可见性,原子性还是需要synchronized来保证。
   -> 虽然保证了可见性,但是线程竞争,虽然能知道某变量变了,但是获取的时候已经变了,不是最新的了。
   -> Java使用的线程调度是抢占式调度。
有问题请指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: