问题标签 [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.

0 投票
4 回答
3960 浏览

android - Dalvik VM & Java 内存模型(Android 上的并发编程)

我正在处理涉及大量并发编程的 Android 项目,并且我将实现一些自定义的线程间通信东西(来自java.util.concurent的那个不太适合我的目的)。

并发编程一般来说并不容易,但使用 Dalvik 似乎更难。要获得正确的代码,您应该知道一些具体的事情以及 Dalvik 出现问题的地方。我只是找不到有关 Dalvik VM 的详细文档。大多数 Android 资源(甚至developer.android.com都专注于平台 API,并且没有提供有关某些非平凡(或低级)事物的任何深入信息)。

例如,Dalvik VM 符合哪个版本的Java 语言规范?根据答案,volatile变量的处理是不同的,并且会影响使用volatile变量的任何并发代码。

已经有一些相关的问题:

fadden的一些答案非常有用,但我仍然想对相关问题进行更详细和完整的理解。

所以下面是我感兴趣的原始问题(如有必要,我将更新列表,因为之前问题的答案将会到来):

  1. 在哪里可以找到有关 Dalvik VM 的详细信息,可以为以下问题提供答案?
  2. Dalvik VM 符合哪个版本的Java 语言规范?
  3. 如果 (2) 的答案是“第三版”,那么 Dalvik 对本规范中所违反的Java 内存模型的支持如何完成?volatile尤其是对变量语义的支持如何完善?
  4. Android 中的双重检查锁定中fadden提供以下评论:

    是的。添加“volatile”关键字后,这将适用于单处理器(所有版本的 Android)和 SMP(3.0“honeycomb”及更高版本)

    这是否意味着具有双核 CPU 但只有 Android 2.3 的三星 Galaxy SII可能会错误地执行并发代码?(当然 Galaxy 只是一个例子,问题是关于任何具有 pre-Android 3.0 平台的多核设备)

  5. 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

0 投票
1 回答
1929 浏览

java - java设置最大堆栈大小

如何设置最大堆栈大小?

我使用 jEdit 在相当大的文件 (73 kb) 中使用正则表达式进行搜索,但由于 StackOverflowException 而失败。

我试图设置 -Xss40m 但它似乎是初始堆栈大小,一段时间后它失败并出现以下异常

如果您向我解释为什么抛出 OutOfMemory 以及如何设置最大堆栈大小,我将不胜感激。

0 投票
1 回答
3349 浏览

java - Java 内存模型和 C++11 内存模型有什么相似之处?

新的 C++ 标准引入了内存模型的概念。Stack Overflow 上已经有关于它的问题,它是什么意思,它如何改变我们用 C++ 编写代码的方式等等。

我有兴趣了解 C++ 内存模型与旧的、众所周知的 Java 内存模型 (1.5) 之间的关系。是一样的吗?是不是很相似?它们有什么显着差异吗?如果是这样,为什么?

Java 内存模型已经存在很长时间了,很多人都非常了解它,所以我想通过将它与 Java 模型进行比较来学习 C++ 内存模型可能会有所帮助,不仅对我有帮助。

0 投票
3 回答
346 浏览

java - Java 发生在线程启动之前

我在某处读到,启动线程对发生之前的关系有一些特殊影响。现在我不确定我的代码是否能保证发生之前的关系,所以请赐教。

我有一个 Dispatcher 线程和一个实现Runnable接口的 Worker 类。Dispatcher 线程创建一个新的 Worker 实例,并通过元素LinkedList的方法在 Worker 实例中填充一个。add

ExecutorService然后 Dispatcher通过该execute方法将 Worker 实例交给 a 。

然后 Worker 类中的 run 方法开始访问和删除LinkedList.

新启动的 Worker 实例是否看到与LinkedListDispatcher 离开时相同的状态?或者可能LinkedList是处于某种不一致的状态?我必须填写LinkedList同步方法吗?

0 投票
1 回答
3753 浏览

java - Java 堆空间监控——我们做错了吗?

我们有一个 Nagios 检查来检查一些 Tomcat 实例上的堆内存状态。它用于从 VM 获取指标的命令如下:

产生如下输出:

如果反对used值大于反对值的 90%,则会启动警报max。这对我来说似乎是有缺陷的,主要是因为价值max可以下降和上升:)

我们应该使用什么信息来正确监控堆空间的消耗?

我应该max与 的值进行比较Xmx吗?

我可以使用以下命令检索 Xmx 的值:

有没有更好的办法?

0 投票
3 回答
129 浏览

java - Java锁和happend-before关系

我不确定我是否正确解释了 javadoc。当使用ReentrantLockafter 调用该lock方法并成功获得锁时,您是否可以访问任何没有任何同步块的对象并且神奇地强制执行happend-before 关系?

我看不出ReentrantLock和我正在处理的对象之间有任何联系,这就是为什么很难相信我可以安全地处理它们。但就是这样,还是我读错了javadoc?

0 投票
4 回答
193 浏览

java - 不可见变量的垃圾收集

我有以下代码:

o2 对象在执行期间是否有资格进行垃圾收集long operation

0 投票
2 回答
1062 浏览

java - Java:易失的隐含订单保证

我的问题是对这个问题的扩展:易失性保证和乱序执行

为了更具体,假设我们有一个简单的类,它在初始化后可以处于两种状态:

初始化的字段被声明为volatile,因此它引入了happens-before 'barrier',以确保不会发生重新排序。由于状态字段仅在写入初始化字段之前 写入并且仅读取初始化字段后读取,因此我可以从状态声明中删除volatile关键字,并且仍然永远不会看到过时的值。问题是:

  1. 这个推理正确吗?
  2. 是否保证不会优化对初始化字段的写入(因为它仅在第一次更改)并且“障碍”不会丢失?
  3. 假设,使用CountDownLatch代替标志作为初始化器,如下所示:

    还会好吗?

0 投票
1 回答
370 浏览

java - Executor.execute() JMM 保证

考虑以下代码片段:

是否保证 messageQueue 在 Runnable 实例尝试检索消息时包含该消息?或者说得更笼统一点:JIT/JVM 可以根据 JMM 对两个函数调用重新排序吗?

0 投票
3 回答
283 浏览

java - Java 发生在同步块之前

我需要一些帮助来理解 Java 内存模型。以下是掌握基本概念的通用示例:

图片我有一个名为的对象实例Shared和两个线程AB. 此外,还有某种Queue带有同步puttake.

线程在方法之前和方法中A修改Shared-instance 。put

问题1:通过同步方法获取-object实例时,所有的变化A都是可见的吗?BSharedtake

Shared问题2:一旦A离开同步方法,内存缓存就会被刷新(所有更改都是可见的) put。如果在- 方法wait()中被调用,会发生什么?即使尚未退出- 方法,也会看到所做的更改?调用时缓存是否也被刷新?putABSharedAsynchronizedwait()