我正在写一些使用ByteBuffer
的东西。 docs of the API中说
没有办法显式释放缓冲区(没有特定于JVM的缓冲区) 反射)。 缓冲区对象要接受GC ,通常需要两个 缓冲区对象变为后,GC循环释放堆外内存 无法访问。
但是我在SO post's accepted answer中阅读
BigMemory通过直接使用JVM进程的内存地址空间 与其他本机Java不同,不受GC 约束的字节缓冲区 对象。
现在我该怎么办,我应该释放创建的缓冲区吗?还是我误会了文档或答案中的某些内容?
答案 0 :(得分:1)
这取决于您如何创建缓冲区,有许多可能的用例。常规ByteBuffer.allocate()
将在堆上创建,并由GC收集。其他选项,例如本机内存可能不会。
Terracotta BigMemory是一种本机堆外内存,不受JVM GC的控制。如果您在这种类型的内存中分配缓冲区,则必须自己清除它。
清除缓冲区是个好主意,即使缓冲区已分配在堆内存中也是如此。 GC将负责收集未使用的缓冲区,但这将需要一些时间。
答案 1 :(得分:1)
LWJGL中BufferUtils
的文档也说:没有办法明确免费 ByteBuffer
。
使用标准机制分配的ByteBuffer
对象(即,通过直接或间接调用ByteBuffer#allocateDirect
)将受到GC的约束,并将最终清除。
您链接的答案似乎特别是指 BigMemory 库。使用JNI,您可以创建一个(直接)ByteBffer
,该ByteBuffer
由GC处理,并且由您决定实际释放基础数据的位置。
但是,一个简短的建议:在处理LWJGL和其他依赖(直接)ByteBuffer
对象的库以将数据传输到本机端时,您应该考虑这些缓冲区的使用模式。特别是对于OpenGL绑定库,您经常需要float
,该空间只能容纳16个class Renderer {
void renderMethodThatIsCalledThousandsOfTimesPerSecond() {
ByteBuffer bb = ByteBuffer.allocateDirect(16 * 4);
fill(bb);
passToOpenGL(bb);
}
}
值(例如,包含要发送到OpenGL的矩阵)。在许多情况下,使用这些缓冲区进行数据传输的方法将被频繁地称为 。
在这种情况下,反复分配这些小的,短暂的缓冲区通常不是一个好主意:
class Renderer {
private final ByteBuffer MATRIX_BUFFER_4x4 = ByteBuffer.allocateDirect(16 * 4);
void renderMethodThatIsCalledThousandsOfTimesPerSecond() {
fill(MATRIX_BUFFER_4x4);
passToOpenGL(MATRIX_BUFFER_4x4);
}
}
创建这些缓冲区和GC会大大降低性能-并以GC暂停的形式令人不安,这可能会导致游戏延迟。
在这种情况下,提取分配并重新使用缓冲区可能是有益的:
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neural_network import MLPRegressor
import numpy as np
from sklearn.model_selection import cross_validate
# Generate some random data
X = np.random.rand(100,5)
Y = np.dot(X, np.random.rand(5))+np.random.rand(100)
# Split into train and test
X_train, X_test, y_train, y_test = train_test_split(X, Y)
# Use 4 fold cross validation on train data
cv_results = cross_validate(MLPRegressor(hidden_layer_sizes=(10,10)), X_train, y_train, cv=4,
scoring=('neg_mean_squared_error'), return_estimator=True)
print (cv_results['test_score'])
# Make predictions on test data
y = np.zeros(len(y_test))
for i, model in enumerate(cv_results['estimator']):
y_hat = model.predict(X_test)
print ("Model {0} MSE Error: {1}".format(i,
mean_squared_error(y_test, y_hat)))
y += y_hat
print ("Average Test MSE Error: {0}".format(
mean_squared_error(y_test, y/len(models))))