java循环体里边创建对象,它的执行过程是怎样的?

问题描述

java循环体里边创建对象,它的执行过程是怎样的?

public class Test
{
public static void main(String[] args)
{
for(int i=0;i<10;i++)
{
Object obj = new Object();
}
}
}

比如说上边这一段代码,越看越不对劲了,它难道是在main方法栈中先后创建了10个引用叫obj?然后每个obj指向不同的new出来的对象?

解决方案

单步调试下就知道了,正常的逻辑是这样的,可能编译器优化后一行代码都没有了。
可以反编译看下生成的字节码。

解决方案二:

一般是循环一次一个新对象,所以如非必要,不要在循环里面创建对象。

解决方案三:

它的确是在main方法栈中先后创建了10个引用叫obj,然后每个obj指向不同的new出来的对象。

关键是:每次循环体执行完后,循环体内定义的代码块局部变量、对象如果没有被继续引用,就立即被销毁了;即obj变量、new出来的对象都被销毁了。

解决方案四:

用内存角度来解释的话,在JVM的方法栈和堆内存这两个内存中,当运行Object obj = new Object();时,在方法栈的栈顶中放入Object obj,然后在堆中生成一个Object对象,最后方法栈中的obj指向Object对象,这时完成一次循环的内存动作。接着第二次循环, new Object();又产生一个新的Object对象,然后方法栈中的obj指向新的Object对象,第一次循环的Object对象没有被任务变量引用,成为了垃圾,等JVM垃圾回收器回收。其它循环以此类推了。
在这里我提一下题外话,JVM有个优秀的算法是,JVM的方法栈,一个方法的调用产生一个栈帧,这个栈帧在方法调用时计算出你有几个局部变量,这个计算会过滤作用域的,如你的循环后面再建立一个局部变量,那JVM认为只有一个局部变量,因为你的Object obj = new Object();在大括号内,出了大括号就没有了,所以只需要一个位置来存放局部变量即可,也就是说运行到大括号时用这个位置来执行代码,出了大括号后下一个局部变量就可以接着使用这个栈的这个位置来执行下面的代码了。

时间: 2024-08-21 04:19:27

java循环体里边创建对象,它的执行过程是怎样的?的相关文章

求解答:java小程序执行过程

问题描述 求解答:java小程序执行过程 package chap14; import java.util.*; interface Generator { T next(); } class Coffee { private static long counter = 0; private final long id = counter++; public String toString() { return getClass().getSimpleName() + " " + id

php内核探索之zend_execute的具体执行过程

解释器引擎最终执行op的函数是zend_execute,实际上zend_execute是一个函数指针,在引擎初始化的时候zend_execute默认指向了execute,这个execute定义在{PHPSRC}/Zend/zend_vm_execute.h: ZEND_API void execute(zend_op_array *op_array TSRMLS_DC) { zend_execute_data *execute_data; zend_bool nested = 0; zend_b

操作系统-有谁能详细介绍一下,环境变量中path路径的执行过程吗?

问题描述 有谁能详细介绍一下,环境变量中path路径的执行过程吗? 就是假设我将环境变量中的path改为了 path=%JAVA_HOME%;bin; 那当我调用java程序进行编译时, 操作系统是通过怎样的路径来寻找 jvm..cfg的呢? ps:我不知道为什么,当我这里写相对路径,如以上的时候: 报一下的错误: 那当我改为绝对路径时,就会正常运行,如一下: 求解,谢谢 解决方案 先在环境变量里定义JAVA HOME,然后在path 里引用 解决方案二: Java_home我定义过了得 解决方

jsp执行过程详解

1.jsp引擎 JSP引擎实际上要把JSP标签.JSP页中的Java代码甚至连同静态HTML内容都转换为大块的Java代码.这些代码块被JSP引擎组织到用户看不到的Java servlet中去,然后servlet自动把JVM(java虚拟机)编译成Java字节码.这样,当网站的访问者请求一个JSP页时,在他不知道的情况下,一个已经生成的.预编译过的servlet实际上将完成所有的工作.非常隐蔽-而又高效.因为servlet是编译过的,所以网页中的JSP代码不需要在每次请求该页时被解释一遍.JSP

java String类创建对象相关

问题描述 java String类创建对象相关 "执行语句 String str = new String("abc") 时,不管字符串池中是否存在"abc" ,直接新建一个字符串"abc"(注意:新建的字符串"abc" 不是在字符串池中),然后将其赋给str." 百度上看到这段,有几个疑问: 1.之前认为new创建String对象时,会先判断常量池中是否存在"abc",如果有就不在常量

第10周-任务0-构造和析构函数的执行过程实例解析

[题目]阅读程序,先分析程序的执行结果,在上机时运行程序进行对照,再通过单步执行跟踪程序的运行,达到理解基类.派生类中构造函数.析构函数执行过程的目的. 程序如下: #include <iostream> using namespace std; class Part  //部件类 { public:     Part();     Part(int i);     ~Part();  private:     int val; }; class Whole: public Part { pu

jbpm-关于JBPM执行过程中出现的异常

问题描述 关于JBPM执行过程中出现的异常 在使用JBPMTestCase进行测试时,测试一段时间之后就会出现一次类似的错误,之前将数据库表删除之后重新创建表,就没有该问题了,现在又出现这个情况了,请各位大神指点.错误异常代码如下. org.hibernate.exception.GenericJDBCException: could not execute native bulk manipulation query at org.hibernate.exception.SQLStateCon

多进程-模拟进程并发执行过程

问题描述 模拟进程并发执行过程 如何模拟进程并发执行过程(Java) 老师讲,主程序调用三个随机函数,以死循环输出 y有更好的办法吗 解决方案 模拟shell进程进程的执行过程 解决方案二: 直接调用进程http://blog.csdn.net/mindhawk/article/details/3447845

线程-Java关于死循环创建对象释放内存的问题

问题描述 Java关于死循环创建对象释放内存的问题 代码: while(true){ //2. Socket s = ss.accept(); // Thread updateThread = new Thread(new UpdateTask(s)); // updateThread.start();//开启线程 // -- 使用线程池 -- threadPool.execute(new UpdateTask(s)); } 上面代码每次new UpdateTask();但是没跳出循环,java