我最近正在考虑释放Java对象占用的内存.在这样做时,我对如何在Java中复制(浅/深)对象以及如何避免在对象仍处于使用状态时意外清除/无效而感到困惑.
考虑以下场景:
ArrayList<Object>作为参数传递给方法.ArrayList<Object>给可由线程处理的runnable类.ArrayList<Object>一个HashMap.现在在这种情况下,如果我打电话,list = null;或者list.clear();对象会发生什么?在这种情况下,对象会丢失,在哪种情况下只将引用设置为null?
我想这与浅层和深层复制对象有关,但在哪些情况下会发生浅层复制,在这种情况下,深层复制是否发生在Java中?
我想了解R在将参数传递给函数,创建变量副本等时使用的逻辑与内存使用情况有关.它什么时候实际创建变量的副本而不是仅仅传递对该变量的引用?特别是我很好奇的情况是:
f <- function(x) {x+1}
a <- 1
f(a)
Run Code Online (Sandbox Code Playgroud)
是a字面意思传递还是被传递的参考?
x <- 1
y <- x
Run Code Online (Sandbox Code Playgroud)
复制参考?什么时候不是这样的?
如果有人能向我解释这一点,我将非常感谢.
我正在尝试在AVCaptureVideoDataOutputSampleBufferDelegate中创建captureOutput返回的CMSampleBuffer副本.
由于CMSampleBuffers来自预先分配的(15)缓冲池,如果我附加对它们的引用,则无法重新收集它们.这会导致所有剩余帧被丢弃.
为了保持最佳性能,某些样本缓冲区直接引用可能需要由设备系统和其他捕获输入重用的内存池.对于未压缩的设备本机捕获,通常会出现这种情况,其中尽可能少地复制内存块.如果多个样本缓冲区长时间引用此类内存池,则输入将无法再将新样本复制到内存中,并且这些样本将被丢弃.
如果您的应用程序通过保留提供的CMSampleBufferRef对象太久而导致丢弃样本,但需要长时间访问样本数据,请考虑将数据复制到新缓冲区中,然后释放样本缓冲区(如果它以前保留过)以便它引用的内存可以重用.
显然我必须复制CMSampleBuffer,但CMSampleBufferCreateCopy()只会创建一个浅拷贝.因此,我得出结论,我必须使用CMSampleBufferCreate().我填写了12个!构造函数需要的参数但遇到了我的CMSampleBuffers不包含blockBuffer的问题(不完全确定那是什么,但似乎很重要).
这个问题已被问过好几次但没有回答.
CMImageBuffer或CVImageBuffer的深层副本并在Swift 2.0中创建CMSampleBuffer的副本
一个可能的答案是"我终于想出如何使用它来创建一个深度克隆.所有复制方法都重用了堆中的数据,这些数据会保留AVCaptureSession.所以我不得不将数据拉入NSMutableData对象然后创建了一个新的样本缓冲区." 在SO上归功于Rob.但是,我不知道如何正确地做到这一点.
如果你有兴趣,这是输出print(sampleBuffer).没有提到blockBuffer,又名CMSampleBufferGetDataBuffer返回nil.有一个imageBuffer,但使用CMSampleBufferCreateForImageBuffer创建"副本"似乎也没有释放CMSampleBuffer.
编辑:由于这个问题已经发布,我一直在尝试更多的方式来复制内存.
我做了用户Kametrixom尝试的相同的事情.这是我尝试同样的想法,首先复制CVPixelBuffer然后使用CMSampleBufferCreateForImageBuffer创建最终的样本缓冲区.但是,这会导致两个错误之一:
CMSampleBufferCreateReadyWithImageBuffer()将失败,结果代码为-12743,"表示给定媒体的格式与给定的格式描述不匹配.例如,与CVImageBuffer配对的格式描述与CMVideoFormatDescriptionMatchesImageBuffer失败."你可以看到Kametrixom和我都CMSampleBufferGetFormatDescription(sampleBuffer)试图复制源缓冲区的格式描述.因此,我不确定为什么给定媒体的格式与给定的格式描述不匹配.
好的,让我用一个简单的例子来解释这个问题:
l = [[0]]*3 # makes the array [[0], [0], [0]]
l[0][0] = 42 # l becomes [[42], [42], [42]]
from copy import deepcopy
m = deepcopy(l) # m becomes [[42], [42], [42]]
m[0][0] = 2 # m becomes [[2], [2], [2]]
Run Code Online (Sandbox Code Playgroud)
这是一个基本的共享参考问题.除了通常情况,当发生这样的问题时,deepcopy我们的朋友.目前,我这样做是为了解决我的deepcopy背叛问题:
l = [[0]]*3 # makes the array [[0], [0], [0]]
import JSON
m = JSON.loads(JSON.dumps(l)) # m becomes [[0], [0], [0]] with no self references
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种效率较低且不那么愚蠢的处理自共享引用的方法.
当然我不会故意制作这样的数组,但是我需要处理有人给我的代码一个的情况.在大型阵列上运行我的"解决方案"很慢,而且我有很多级别的嵌套数组,我不能为这些野兽制作这么大的字符串.
所以$ array是一个数组,其中所有元素都是引用.
我想将这个数组追加到另一个名为$ results的数组(在循环中),但由于它们是引用,PHP复制引用,$ results充满了相同的元素.
到目前为止,最佳工作解决方案是:
$results[] = unserialize(serialize($array));
Run Code Online (Sandbox Code Playgroud)
我担心这会非常低效.有一个更好的方法吗?
鉴于以下课程:
class A
{
public List<B> ListB;
// etc...
}
Run Code Online (Sandbox Code Playgroud)
哪个B是可以继承/包含其他类的另一个类.
鉴于这种情况:
A 是一个大类,包含许多引用类型B,[Serializable]因为我无法访问源代码B以下执行深度复制的方法不起作用:
ICloneable或MemberwiseClone作为类A包含许多引用类型A,因为类很大并且不断被添加到,并且包含B无法深度复制的类(如)B,没有可用的源代码)[Serializable]我怎样才能深造课A?
from multiprocessing import Process
# c is a container
p = Process(target = f, args = (c,))
p.start()
Run Code Online (Sandbox Code Playgroud)
我假设将深层副本c传递给函数,f因为浅层副本在新进程的情况下没有任何意义(新进程无法访问调用进程中的数据).
但这个深层副本是如何定义的?这里有一整集的笔记中copy.deepcopy()的文档,做所有这些说明适用于这里?该multiprocessing文件说什么?
我想对包括所有属性的对象进行深层复制.
experiment_old有10个试验.我希望通过10次试验将所有内容复制到experiment_new中.experiment_old还应该保留10个试用信息.
但是,我在下面尝试过的所有情况都会很好地复制一切,但是experiment_old没有10个试验信息.他们只是出现在experiment_new上.
对这些案例进行深层复制的最佳方法是什么.
情况1:
@experiment_new = Experiment.create(@experiment_old.attributes.merge(:trials => experiment_old.trails))
Run Code Online (Sandbox Code Playgroud)
案例2:
@experiment_new = Marshal.load(Marshal.dump(@experiment_old.trials))
Run Code Online (Sandbox Code Playgroud)
案例3:
@experiment_new = @experiment_old.clone
Run Code Online (Sandbox Code Playgroud)
这是模型:
class Experiment < ActiveRecord::Base
belongs_to :experimenter
has_many :trials
has_many :participants
end
class Trial < ActiveRecord::Base
belongs_to :experiment
belongs_to :datum
belongs_to :condition
has_one :result_trial
end
Run Code Online (Sandbox Code Playgroud) 我理解浅层复制和深层复制之间的区别,就像我在课堂上学到的那样.但是以下没有意义
import copy
a = [1, 2, 3, 4, 5]
b = copy.deepcopy(a)
print(a is b)
print(a[0] is b[0])
----------------------------
~Output~
>False
>True
----------------------------
Run Code Online (Sandbox Code Playgroud)
print(a[0] is b[0])由于在深层副本中的不同内存位置重新创建对象及其组成元素,因此不应评估为False?我正在测试这个,因为我们已经在课堂上讨论了它,但它似乎没有用.
有人可以解释copyKotlin数据类的方法究竟是如何工作的吗?对于某些成员来说,实际上并没有创建(深层)副本,并且引用仍然是原始的.
fun test() {
val bar = Bar(0)
val foo = Foo(5, bar, mutableListOf(1, 2, 3))
println("foo : $foo")
val barCopy = bar.copy()
val fooCopy = foo.copy()
foo.a = 10
bar.x = 2
foo.list.add(4)
println("foo : $foo")
println("fooCopy: $fooCopy")
println("barCopy: $barCopy")
}
data class Foo(var a: Int,
val bar: Bar,
val list: MutableList<Int> = mutableListOf())
data class Bar(var x: Int = 0)
Run Code Online (Sandbox Code Playgroud)
输出:
foo:Foo(a = 5,bar = Bar(x = 0),list = [1,2,3])
foo:Foo(a = 10,bar = Bar(x = …
deep-copy ×10
python ×3
copy ×2
reference ×2
c# ×1
cloning ×1
data-class ×1
data.table ×1
ios ×1
java ×1
kotlin ×1
nested-lists ×1
null ×1
php ×1
pool ×1
python-3.x ×1
r ×1
shallow-copy ×1
swift ×1