问题标签 [java-memory-model]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
android - Dalvik VM & Java 内存模型(Android 上的并发编程)
我正在处理涉及大量并发编程的 Android 项目,并且我将实现一些自定义的线程间通信东西(来自java.util.concurent的那个不太适合我的目的)。
并发编程一般来说并不容易,但使用 Dalvik 似乎更难。要获得正确的代码,您应该知道一些具体的事情以及 Dalvik 出现问题的地方。我只是找不到有关 Dalvik VM 的详细文档。大多数 Android 资源(甚至developer.android.com都专注于平台 API,并且没有提供有关某些非平凡(或低级)事物的任何深入信息)。
例如,Dalvik VM 符合哪个版本的Java 语言规范?根据答案,volatile
变量的处理是不同的,并且会影响使用volatile
变量的任何并发代码。
已经有一些相关的问题:
fadden的一些答案非常有用,但我仍然想对相关问题进行更详细和完整的理解。
所以下面是我感兴趣的原始问题(如有必要,我将更新列表,因为之前问题的答案将会到来):
- 在哪里可以找到有关 Dalvik VM 的详细信息,可以为以下问题提供答案?
- Dalvik VM 符合哪个版本的Java 语言规范?
- 如果 (2) 的答案是“第三版”,那么 Dalvik 对本规范中所违反的Java 内存模型的支持如何完成?
volatile
尤其是对变量语义的支持如何完善? 在Android 中的双重检查锁定中,fadden提供以下评论:
是的。添加“volatile”关键字后,这将适用于单处理器(所有版本的 Android)和 SMP(3.0“honeycomb”及更高版本)
这是否意味着具有双核 CPU 但只有 Android 2.3 的三星 Galaxy SII可能会错误地执行并发代码?(当然 Galaxy 只是一个例子,问题是关于任何具有 pre-Android 3.0 平台的多核设备)
在Dalvik 的内存模型与 Java 的相同吗?fadden用以下句子提供答案:
就 JSR-133 而言,当前发布的 Dalvik 版本没有完全正确
这是否意味着任何现有的正确并发 Java 代码都可能在发布此评论之前发布的任何 Android 版本上无法正常运行?
更新#1:回复@gnat 的评论(太长也不能发表评论)
@gnat 发表评论:
@Alexey Dalvik 不符合任何 JLS 版本,因为符合要求需要通过 JCK,这不是 Dalvik 的选项。这是否意味着您甚至不能应用标准 Java 编译器,因为它符合标准规范?那有关系吗?如果是,如何?
好吧,我的问题有点模棱两可。我的真正意思是JLS不仅是 Java 编译器实现的规则,而且是任何JVM实现的隐含指南。事实上,例如, JLS声明某些类型的读取和写入是原子操作。这对编译器编写器来说不是很有趣,因为读/写只翻译成单个操作码。但对于任何应该正确实现这些操作码的JVM实现来说,这都是必不可少的。现在你应该明白我在说什么了。虽然 Dalvik 接受并执行使用标准 Java 编译器编译的程序,但没有任何保证它们被正确执行(如您所料)只是因为没有人(也许 Dalvik 的开发人员除外)知道程序中使用的所有 JLS 功能是否都受到 Dalvik 的支持。
很明显,JCK不是 Dalvik 的一个选项,这没关系,但程序员真的应该知道在 Dalvik 上执行代码时他们可能依赖JLS的哪些功能。但是文档中没有任何关于此的文字。虽然您可能期望像 =、+、-、* 等最简单的运算符都能像您期望的那样工作,但像变量语义这样的非平凡特性(在JLS的第 2 版和第 3 版中有所不同)呢?后者并不是您在JLS中可能发现的最重要的东西,尤其是在Java Memory Model中。volatile
java - java设置最大堆栈大小
如何设置最大堆栈大小?
我使用 jEdit 在相当大的文件 (73 kb) 中使用正则表达式进行搜索,但由于 StackOverflowException 而失败。
我试图设置 -Xss40m 但它似乎是初始堆栈大小,一段时间后它失败并出现以下异常
如果您向我解释为什么抛出 OutOfMemory 以及如何设置最大堆栈大小,我将不胜感激。
java - Java 内存模型和 C++11 内存模型有什么相似之处?
新的 C++ 标准引入了内存模型的概念。Stack Overflow 上已经有关于它的问题,它是什么意思,它如何改变我们用 C++ 编写代码的方式等等。
我有兴趣了解 C++ 内存模型与旧的、众所周知的 Java 内存模型 (1.5) 之间的关系。是一样的吗?是不是很相似?它们有什么显着差异吗?如果是这样,为什么?
Java 内存模型已经存在很长时间了,很多人都非常了解它,所以我想通过将它与 Java 模型进行比较来学习 C++ 内存模型可能会有所帮助,不仅对我有帮助。
java - Java 发生在线程启动之前
我在某处读到,启动线程对发生之前的关系有一些特殊影响。现在我不确定我的代码是否能保证发生之前的关系,所以请赐教。
我有一个 Dispatcher 线程和一个实现Runnable
接口的 Worker 类。Dispatcher 线程创建一个新的 Worker 实例,并通过元素LinkedList
的方法在 Worker 实例中填充一个。add
ExecutorService
然后 Dispatcher通过该execute
方法将 Worker 实例交给 a 。
然后 Worker 类中的 run 方法开始访问和删除LinkedList
.
新启动的 Worker 实例是否看到与LinkedList
Dispatcher 离开时相同的状态?或者可能LinkedList
是处于某种不一致的状态?我必须填写LinkedList
同步方法吗?
java - Java 堆空间监控——我们做错了吗?
我们有一个 Nagios 检查来检查一些 Tomcat 实例上的堆内存状态。它用于从 VM 获取指标的命令如下:
产生如下输出:
如果反对used
值大于反对值的 90%,则会启动警报max
。这对我来说似乎是有缺陷的,主要是因为价值max
可以下降和上升:)
我们应该使用什么信息来正确监控堆空间的消耗?
我应该max
与 的值进行比较Xmx
吗?
我可以使用以下命令检索 Xmx 的值:
有没有更好的办法?
java - Java锁和happend-before关系
我不确定我是否正确解释了 javadoc。当使用ReentrantLock
after 调用该lock
方法并成功获得锁时,您是否可以访问任何没有任何同步块的对象并且神奇地强制执行happend-before 关系?
我看不出ReentrantLock
和我正在处理的对象之间有任何联系,这就是为什么很难相信我可以安全地处理它们。但就是这样,还是我读错了javadoc?
java - 不可见变量的垃圾收集
我有以下代码:
o2 对象在执行期间是否有资格进行垃圾收集long operation
?
java - Java:易失的隐含订单保证
我的问题是对这个问题的扩展:易失性保证和乱序执行
为了更具体,假设我们有一个简单的类,它在初始化后可以处于两种状态:
初始化的字段被声明为volatile,因此它引入了happens-before 'barrier',以确保不会发生重新排序。由于状态字段仅在写入初始化字段之前 写入并且仅在读取初始化字段后读取,因此我可以从状态声明中删除volatile关键字,并且仍然永远不会看到过时的值。问题是:
- 这个推理正确吗?
- 是否保证不会优化对初始化字段的写入(因为它仅在第一次更改)并且“障碍”不会丢失?
假设,使用CountDownLatch代替标志作为初始化器,如下所示:
还会好吗?
java - Executor.execute() JMM 保证
考虑以下代码片段:
是否保证 messageQueue 在 Runnable 实例尝试检索消息时包含该消息?或者说得更笼统一点:JIT/JVM 可以根据 JMM 对两个函数调用重新排序吗?
java - Java 发生在同步块之前
我需要一些帮助来理解 Java 内存模型。以下是掌握基本概念的通用示例:
图片我有一个名为的对象实例Shared
和两个线程A
和B
. 此外,还有某种Queue
带有同步put
和take
.
线程在方法之前和方法中A
修改Shared
-instance 。put
问题1:通过同步方法获取-object实例时,所有的变化A
都是可见的吗?B
Shared
take
Shared
问题2:一旦A
离开同步方法,内存缓存就会被刷新(所有更改都是可见的) put
。如果在- 方法wait()
中被调用,会发生什么?即使尚未退出- 方法,也会看到所做的更改?调用时缓存是否也被刷新?put
A
B
Shared
A
synchronized
wait()