局部变量中引用的Java实例变量。内存、线程安全和终结
我有一个类MyClass,它有一个带有变量的方法——OtherClass的一个实例,如下所示局部变量中引用的Java实例变量。内存、线程安全和终结,java,garbage-collection,java-threads,java-memory-model,Java,Garbage Collection,Java Threads,Java Memory Model,我有一个类MyClass,它有一个带有变量的方法——OtherClass的一个实例,如下所示 public class Myclass{ public void meth1(){ OtherClass other = new OtherClass(); other.perform(); } } public class OtherClass{ private Map<String, String> ops = new HashMa
public class Myclass{
public void meth1(){
OtherClass other = new OtherClass();
other.perform();
}
}
public class OtherClass{
private Map<String, String> ops = new HashMap<>();
public void perform(){
// put/ remove values in ops
}
}
公共类Myclass{
公共图书馆1({
OtherClass other=新的OtherClass();
其他。执行();
}
}
公共类其他类{
私有映射操作=新的HashMap();
公开执行{
//在ops中放置/删除值
}
}
这是一个多线程环境
当线程执行meth1()方法时,映射在哪里创建?成堆?声明为实例变量的映射是否存在线程安全问题wrt。
当局部变量被垃圾收集时,我假设map也被垃圾收集。如果我错了,请改正
注意:我知道在多线程环境中使用实例变量时会出现数据损坏
不过,这与场景略有不同,将在堆上创建
其他类
对象,并在堆栈上创建对该对象的引用。由于堆栈限制
,此代码是完全线程安全的。只有当对象的状态在多个线程之间共享时,才会出现线程安全问题。由于该对象只能由调用该方法的线程访问,因此它不是共享的。一旦堆栈弹出,对象将被垃圾收集。将在堆上创建OtherClass
对象,并在堆栈上创建对该对象的引用。由于堆栈限制
,此代码是完全线程安全的。只有当对象的状态在多个线程之间共享时,才会出现线程安全问题。由于该对象只能由调用该方法的线程访问,因此它不是共享的。一旦堆栈弹出,对象将被垃圾收集
当线程执行meth1()方法时,映射在哪里创建?
成堆
对。使用newwhatever()
创建的所有内容都存储在堆中,OtherClass
实例及其HashMap
(因为其初始化包括newhashmap()
表达式)。每次执行newwhere()
,堆上都会有一个全新的实例
声明为实例的映射是否存在线程安全问题
变数
不,不在你的例子中。只有当多个线程访问同一个OtherClass
实例时,线程安全才可能成为一个问题。在您的例子中,每个执行线程都会创建其各自的OtherClass
实例(在局部变量other
中),只使用该实例,而不会将其分发给其他线程可能看到它的任何地方
当本地变量被垃圾收集时,我假设map是
还收集垃圾
是的,只要不添加将地图分发给软件其他部分的代码
当实例不再被任何“活动”变量/参数/对象/引用时,它们将被垃圾收集。。。在您的例子中,ops
HashMap仅由其所包含的OtherClass
实例的ops
字段引用(存储)。因此,当这个实例不再可访问时,映射也将变得不可访问,从而准备进行垃圾收集
一句话:垃圾收集不会发生在某些东西变得不可访问的同一时刻,它是由一些精心设计的优化算法安排的。你唯一能确定的是它会在你的内存用完之前发生
注意:我知道当我们有实例变量时,会出现数据损坏
但在多线程环境中,这略有不同
情景
事实恰恰相反:如果没有实例或类字段,就不会遇到线程安全/数据损坏问题
真实情况是:如果在多线程设置中使用实例或类字段,则必须小心。但例如,只读实例字段(仅在构造函数中设置且以后不会更改的字段)通常是安全的
当线程执行meth1()方法时,映射在哪里创建?
成堆
对。使用newwhatever()
创建的所有内容都存储在堆中,OtherClass
实例及其HashMap
(因为其初始化包括newhashmap()
表达式)。每次执行newwhere()
,堆上都会有一个全新的实例
声明为实例的映射是否存在线程安全问题
变数
不,不在你的例子中。只有当多个线程访问同一个OtherClass
实例时,线程安全才可能成为一个问题。在您的例子中,每个执行线程都会创建其各自的OtherClass
实例(在局部变量other
中),只使用该实例,而不会将其分发给其他线程可能看到它的任何地方
当本地变量被垃圾收集时,我假设map是
还收集垃圾
是的,只要不添加将地图分发给软件其他部分的代码
当实例不再被任何“活动”变量/参数/对象/引用时,它们将被垃圾收集。。。在您的例子中,ops
HashMap仅由其所包含的OtherClass
实例的ops
字段引用(存储)。因此,当这个实例不再可访问时,映射也将变得不可访问,从而准备进行垃圾收集
一句话:垃圾收集不会发生在某些东西变得不可访问的同一时刻,它是由一些精心设计的优化算法安排的。你唯一能确定的是它会在你的内存用完之前发生
注意:我知道当我们有实例变量时,会出现数据损坏
在多个