首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Java内存储器模型笔记

2012-12-19 
Java内存模型笔记题记:??? 看到C/C++写的内存池,不免了解下。同时学习下Java的Memory Model,学习和理解基于

Java内存模型笔记

题记:
??? 看到C/C++写的内存池,不免了解下。同时学习下Java的Memory Model,学习和理解基于http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#jsr133

?

关于Java Memory Model

What is a memory model, anyway?

什么是内存模型?
In multiprocessor systems, processors generally have one or more layers of memory cache, which improves performance both by speeding access to data (because the data is closer to the processor) and reducing traffic on the shared memory bus (because many memory operations can be satisfied by local caches.)

At the processor level, a memory modeldefines necessary and sufficient conditions for knowing that writes tomemory by other processors are visible to the current processor, andwrites by the current processor are visible to other processors. Someprocessors exhibit a strong memory model, where all processors seeexactly the same value for any given memory location at alltimes. Other processors exhibit a weaker memory model, where specialinstructions, called memory barriers, are required to flush orinvalidate the local processor cache in order to see writes made byother processors or make writes by this processor visible toothers. These memory barriers are usually performed when lock andunlock actions are taken; they are invisible to programmers in a highlevel language.

多核处理器通常都有1,2级或更多缓存,在处理器级别,内存模型通常规定了某处理器在写内存的时候需要对其他处理器都相互可见。一些处理器被设计成strong memory model,能让所有处理器在任何时候看到某内存里的值都是一样的。而有些处理器被设计成weawk memory model,拥有一个memory barrier的特殊结构,后面的没看明白。不管什么设计对于Programmer来说是透明的。

?

Recent trends in processor design have encouragedweaker memory models, because the relaxations they make for cacheconsistency allow for greater scalability across multiple processorsand larger amounts of memory.

而“弱内存模型”在多处理器中,更能带来更好的可测试性和更多的内存。

?

The Java Memory Model describes whatbehaviors are legal in multithreaded code, and how threads mayinteract through memory. It describes the relationship betweenvariables in a program and the low-level details of storing andretrieving them to and from memory or registers in a real computersystem. It does this in a way that can be implemented correctly usinga wide variety of hardware and a wide variety of compileroptimizations.

JAVA内存模型描述多线程操作内存的行为。描述了程序中的变量在内存中如何存储和获取的,或者在计算机中如何注册的。Java内存模型需要在各种硬件和编译器优化中正确实现这些东西。

?

Do other languages, like C++, have a memory model?Most other programming languages, suchas C and C++, were not designed with direct support for multithreading. The protections that these languages offer against the kindsof reorderings that take place in compilers and architectures areheavily dependent on the guarantees provided by the threadinglibraries used (such as pthreads), the compiler used, and the platformon which the code is run.

C/C++本身貌似不直接支持多线程,而是靠一些lib,比如pthreads。

The Java Memory Model was an ambitiousundertaking; it was the first time that a programming languagespecification attempted to incorporate a memory model which couldprovide consistent semantics for concurrency across a variety ofarchitectures.

?

What is meant by reordering?

There are a number of cases in whichaccesses to program variables (object instance fields, class staticfields, and array elements) may appear to execute in a different orderthan was specified by the program. The compiler is free to takeliberties with the ordering of instructions in the name ofoptimization. Processors may execute instructions out of order undercertain circumstances. Data may be moved between registers, processorcaches, and main memory in different order than specified by theprogram.For example, if a thread writes to fielda and then to field b, and the value of bdoes not depend on the value of a, then the compiler is freeto reorder these operations, and the cache is free to flush bto main memory before a.Most of the time, one thread doesn't care what the other is doing. But when it does, that's what synchronization is for.

大概意思是说代码的运行在程序里和寄存器、CPU缓存、主内存里是不一样的。这里举了个例子,比如一个写线程先写变量a,然后写变量b,a和b相互没有依赖的话,那么在缓存里,b可能会先于a写入主存中。大多数情况,单线程是不用关心这种顺序,但多线程的话,就需要用synchronize来保证顺序了。

?

What was wrong with the old memory model?

Nothing in the old memory modeltreated final fields differently from any other fiel.it was possible for a thread to see thedefault value of the field, and then at some later time see itsconstructed value.

在旧内存模型中,final变量和其他变量一样。比如String那种变量,这样会导致某一线程对于同一个final变量读取到不同的两个值。

?

?

What does synchronization do?Synchronization ensures that memory writes by athread before or during a synchronized block are made visible in apredictable manner to other threads which synchronize on the samemonitor.

In the new memory model any memory operationswhich were visible to a thread before exiting a synchronized block arevisible to any thread after it enters a synchronized block protectedby the same monitor, since all the memory operations happen before therelease, and the release happens before the acquire.

同步就是确保在写内存的时候只允许一个thread操作,而其他thread等待,当第一个thread写完从block出来后,下个线程才允许进入并查看修改后的内存,但需要第一个thread退出synchronization block后才可见修改后的值。而新模型中,第一个线程在block中发生写内存操作,其他threads就可以看到,而不需要等待当前thread退出block的时候。

?

How can final fields appear to change their values?

JSR133说这样做是愚蠢的,原因是初始化instance变量和执行getInstance()方法的顺序是能被编译器或缓存打乱的,在旧模型中,是没有办法避免这个问题。原因没看明白。

?

Many people assumed that the use of thevolatile keyword would eliminate the problems that arise whentrying to use the double-checked-locking pattern. In JVMs prior to1.5, volatile would not ensure that it worked (your mileagemay vary). Under the new memory model, making the instancefield volatile will "fix" the problems with double-checkedlocking, because then there will be a happens-before relationshipbetween the initialization of the Something by theconstructing thread and the return of its value by the thread thatreads it.

Instead, use the Initialization OnDemand Holder idiom, which is thread-safe and a lot easier tounderstand:

很多人认为volatile可以解决这个问题,在旧模型中不行,在新模型中”可以“,没看明白。

最好的线程安全方式如下:

?


在写这个的时候,想了一个很傻的问题,如果我把-Xmx=1024m -Xmn=1m,运行个很大的app,app会不会outmemory,后来想了下才知道自己很傻,显然不会,GC会启动,object入survivor区域,eden又有内存了。

?

写内存池貌似需要考虑很多问题,这是个非常容易出现crash的地方。

内存池大小

池不够,需要增加内存池

需要对象大小是否要split

是否需要给每个对象加head

内存池锁问题

共享内存

池中寻找空闲内存的算法

平台相关性

?

?

?

?

?

1 楼 C_J 2011-04-18   JE有个BUG,在博客里之前发布的文章,再发布到论坛竟然不认为是论坛的新帖,需要顶 一 下 2 楼 C_J 2011-04-18   全部文章:http://www.cs.umd.edu/users/pugh/java/memoryModel/ 3 楼 ctoeye 2011-04-18   莫名其妙,搞什么鬼东西。这三个东西有什么不好明白的?用得着长篇大乱?
以前单例一般方法加synchronize,保证取实例时的线程安全。但性能有问题,于是出现volatile属性配合双得加锁double-check,用来提高性能。但是volatile在旧版本jdk中往往不生效,这是java本身的问题。在新版本的jdk中没有问题。 4 楼 C_J 2011-04-18   ctoeye 写道莫名其妙,搞什么鬼东西。这三个东西有什么不好明白的?用得着长篇大乱?
以前单例一般方法加synchronize,保证取实例时的线程安全。但性能有问题,于是出现volatile属性配合双得加锁double-check,用来提高性能。但是volatile在旧版本jdk中往往不生效,这是java本身的问题。在新版本的jdk中没有问题。

哦,我不懂,只是来学习下,表鸡冻。 5 楼 独爱Java 2011-04-20   好像实际用处并不是很大,只是多了解了有这个东西而已。。。 6 楼 C_J 2011-04-20   独爱Java 写道好像实际用处并不是很大,只是多了解了有这个东西而已。。。

其实上面有几个知识点

1个关于构造线程安全的构造函数的
2个关于volatile赋值顺序的问题

热点排行