[转]Java内存对象的逃逸分析

逃逸分析英文作Escape Analysis。在计算机语言编译器优化原理中,逃逸分析是指分析指针动态范围的方法,它同编译器优化原理的指针分析和外形分析相关联。

当变量(或者对象)在方法中分配后,其指针有可能被返回或者被全局引用,这样就会被其他过程或者线程所引用,这种现象称作指针(或者引用)的逃逸(Escape)。

在Java 并发编程书里有个例子程序清单3-7 谈到 this escape。 开始没有想明白, 仔细琢磨了些时间发现代码主要的问题是在建构函数中创建了一个匿名类,然后发布了这个匿名类。

Java代码  

  1. import java.util.*;
  2. public class ThisEscape {
  3. private final int num;
  4. public ThisEscape(EventSource source) {
  5. source.registerListener(
  6. new EventListener() {
  7. public void onEvent(Event e) {
  8. doSomething(e);
  9. }
  10. });
  11. num = 42;
  12. }
  13. private void doSomething(Event e) {
  14. if (num != 42) {
  15. System.out.println("Race condition detected");
  16. }
  17. }
  18. }

这段代码如果被 编译,然后JD-GUI  反编译看到得 doSomething(e); 就会变成

ThisEscape.this.doSomething(e);   这个应该是 java  inner class 调用外部class的标准方式 -  外部类名.this.方法名

如果进一步的深究, 我们知道  ThisEscape编译后会有两个class 文件。一个是  ThisEscape.class, 另个一个会是  ThisEscape$1.class 给这个匿名类。

它们的内容差不多是这个样子的

Java代码  

  1. public class ThisEscape {
  2. private final int num;
  3. public ThisEscape(EventSource source) {
  4. source.registerListener(new <strong><span style="color: #ff0000;">ThisEscape$1</span></strong>(this));
  5. num = 42;
  6. }
  7. private void doSomething(Event e) {
  8. if (num != 42)
  9. System.out.println(
  10. "Race condition detected ");
  11. }
  12. static void access$000(ThisEscape _this, Event event) {
  13. _this.doSomething(event);
  14. }
  15. }

Java代码  

  1. class ThisEscape$1 implements EventListener {
  2. final ThisEscape this$0;
  3. ThisEscape$1(<span style="color: #ff0000;">ThisEscape thisescape</span>) {
  4. this$0 = thisescape;
  5. super();
  6. }
  7. public void onEvent(Event e) {
  8. ThisEscape.access$000(this$0, e);
  9. }
  10. }

这样如果 new ThisEscape$1(this) 在另外的线程中被执行的话, 就可能导致 逃逸出去的this 的 num  还没有 执行 num = 42;   Race condition detected 会不时的显示在console 里面。

时间: 2024-10-07 09:42:19

[转]Java内存对象的逃逸分析的相关文章

Java内存模型JMM简单分析

参考博文:http://blog.csdn.net/suifeng3051/article/details/52611310 http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html    http://www.cnblogs.com/dolphin0520/p/3613043.html 一.Java内存区域的划分 由于Java程序是交给JVM执行的,所以我们在谈Java内存区域分析的时候事实上是指JVM内存区域划分. 根

一个Java内存可见性问题的分析

如果熟悉Java并发编程的话,应该知道在多线程共享变量的情况下,存在内存可见性问题: 在一个线程中对某个变量进行赋值,在另外一个线程中读取该变量的值,读取到的可能仍然是以前的值: 这里并非说的是时序的问题,例如读取操作在赋值操作之前执行了,而是说, 即使在另外一个线程中循环读取该变量的值,也可能永远看不到变量的最新值,或者一段时间内看不到. 请看下面的代码片 1 public class Main extends Thread { 2 private static boolean flag =

JVM的学习3_____逃逸分析与栈上分配

之前有提到过,为了提高GC的回收效率,对象实例的内存分配不一定必须存在于堆区中,还可采用堆外分配.而最常见的堆外分配就是采用逃逸分析筛选出未发生逃逸的对象,在栈帧中分配内存空间. 逃逸分析:就是分析出对象的作用域.当一个对象在方法体内声明后,该对象的引用被其他外部所引用时该对象就发生了逃逸,反之就会在栈帧中为对象分配内存空间. 根据逃逸分析在栈帧中分配的对象内存,不会使用GC进行垃圾回收.因为栈会随着方法的开始而创建,结束而销毁. 原文地址:https://www.cnblogs.com/xbf

深入理解Java中的逃逸分析

在Java的编译体系中,一个Java的源代码文件变成计算机可执行的机器指令的过程中,需要经过两段编译,第一段是把.java文件转换成.class文件.第二段编译是把.class转换成机器指令的过程. 第一段编译就是javac命令. 在第二编译阶段,JVM 通过解释字节码将其翻译成对应的机器指令,逐条读入,逐条解释翻译.很显然,经过解释执行,其执行速度必然会比可执行的二进制字节码程序慢很多.这就是传统的JVM的解释器(Interpreter)的功能.为了解决这种效率问题,引入了 JIT(即时编译)

学java教程之java内存分析

学编程吧学java教程之java内存分析发布了,欢迎大家通过xuebiancheng8.com来访问 java的内存模型是java中非常重要的知识,也是面试的时候重点. java虚拟机的内存模型中和我们打交道多的分为这么几个区域 堆区,栈区,方法区. 其中方法区又分为常量池,静态区和方法区. 这几部分分别是干嘛的呢,堆区是用来存放new出来的对象的,堆区是应用程序共享的区域. 栈区又叫方法栈,程序在运行的时候,代码要在方法栈中运行,运行的代码需要放在方法栈中来执行,然后寄存器一行一行加载执行.

Java内存泄漏分析与解决方案

Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最快最好的检测程序的稳定性,防止系统崩盘,作者用自已的亲身经历与各位网友分享解决这些问题的办法. 作为Internet最流行的编程语言之一,Java现正非常流行.我们的网络应用程序就主要采用Java语言开发,大体上分为客户端.服务器和数据库三个层次.在进入测试过程中,我们发现有一个程序模块系统内存和CPU资源消耗急剧增加,持续增长到出现java.lang.Ou

(转)java内存泄漏的定位与分析

转自:http://blog.csdn.net/x_i_y_u_e/article/details/51137492 1.为什么会发生内存泄漏 java 如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题. 编写java程序最为方便的地方就是我们不需要管理内存的分配和释放,一切由jvm来进行处理,当java对象不再被应用时,等到堆内存不够用时,jvm会进行垃圾回收,清除这些对象占用的堆内存空间,如果对象一直被应用,jvm无法对其进行回收,创建新的对象时

java内存管理的分析

java 中的内存分为四个部分: stack(栈):存放基本类型的数据和对象的引用,即存放局部变量. Note: 如果存放的是基本类型数据(非静态变量),则直接将变量名和值存入stack中. 如果存放的是引用类型,则将变量名存入栈,然后指向它new出的对象(存放在堆中). heap(堆)存放 new 出来的东西. data segment(数据区):分为静态区和常量区(常量池) 静态区(static segment): 存放在对象中用 static 定义的静态成员(即静态变量,如果该静态变量是基

转:【Java并发编程】之十六:深入Java内存模型——happen-before规则及其对DCL的分析(含代码)

转载请注明出处:http://blog.csdn.net/ns_code/article/details/17348313 happen-before规则介绍 Java语言中有一个"先行发生"(happen-before)的规则,它是Java内存模型中定义的两项操作之间的偏序关系,如果操作A先行发生于操作B,其意思就是说,在发生操作B之前,操作A产生的影响都能被操作B观察到,"影响"包括修改了内存中共享变量的值.发送了消息.调用了方法等,它与时间上的先后发生基本没有