我试图通过使用内存映射特定文件在两个或更多JVM之间实现一种共享缓存MappedByteBuffer.从规范中我看到,当我们使用MappedByteBuffer.load()它时应该将数据加载到直接缓冲区.我对此有几个问题.
我的代码片段::
RandomAccessFile file = new RandomAccessFile("file.txt","rw");
FileChannel fc = file.getChannel();
MappedByteBuffer buf5 = fc.map(MapMode.READ_WRITE, 0, fc.size());
//ByteBuffer buf6 = ByteBuffer.allocateDirect(100000000);
buf5.load();
try
{
Class c = Class.forName("java.nio.Bits");
Field f = c.getDeclaredField("reservedMemory");
f.setAccessible(true);
long reservedMemory = f.getLong(null);
f = c.getDeclaredField("maxMemory");
f.setAccessible(true);
System.out.println(
"Direct Memory Usage: "+ reservedMemory +"/"+ f.getLong(null)+"\n");
}
catch (Throwable t)
{
}
Run Code Online (Sandbox Code Playgroud)
对于直接内存使用(File.txt为1 GB),上述代码的输出为0字节.但是,如果我取消注释该行..
ByteBuffer buf6 = ByteBuffer.allocateDirect(100000000);
Run Code Online (Sandbox Code Playgroud)
我得到100MB的直接内存使用率.无法理解为什么会这样,至于为什么我没有得到任何直接的内存使用(即当行被注释掉)
虽然上述代码的直接内存使用率为0 B,但我确实看到进程的常驻内存(使用unix top)增加了1 GB.但是如果我在盒子上做了"free -m",我看不到任何内存使用量的增加.
在这两种情况下,我对内存最终的位置感到有些困惑.
谢谢!
我试图"清理"a ByteBuffer为所有零字节(全部0x00).我试图遍历缓冲区中的所有位置并将它们设置为0x00,但效率很差.有没有更好的方法来快速清除ByteBuffer- 类似于什么BitSet.clear()?
请注意,ByteBuffer.clear()在这种情况下,对我来说这不是一个合适的解决方案 - 我必须擦除缓冲区内的所有数据,而不仅仅是将指针重置为开头.
任何提示?
编辑:ByteBuffer用作哈希表的一部分,它维护哈希表条目的引用.每次需要刷新哈希表时,我都必须重置哈希表条目以便以后的哈希表插入.由于以随机方式访问哈希表,我不能简单地清除()字节缓冲区的状态.
我在Swift中有一个protobuf v2,我试图将它附加到另一个protobuf上.这就是我正在尝试的:
let attachment = getAttachment(id: 987) //From cloud database
var protosData = NSMutableData(data: attachment)
items.forEach { //Some struct array of values
guard let proto = try? MyProtoBuf.Builder()
.setEpochMillis($0.date.epochMilliseconds)
.setValue($0.value)
.build() else { return }
protosData.appendData(proto.data())
}
saveAttachment(protosData) //Store to cloud
Run Code Online (Sandbox Code Playgroud)
看起来我似乎是在破坏数据,因为我在阅读时遇到了这个错误:
malloc: *** mach_vm_map(size=2749415424) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Run Code Online (Sandbox Code Playgroud)
也许这是我的回读值不正确,这是我正在做的从存储中读取附加数据:
extension GeneratedMessageProtocol {
static func getStreamData(data: NSData) -> [Self] {
var messages = [Self]() …Run Code Online (Sandbox Code Playgroud) 这是:
ByteBuffer buf = ByteBuffer.allocate(1000);
Run Code Online (Sandbox Code Playgroud)
...初始化的唯一方法是ByteBuffer?
如果我不知道需要分配多少字节怎么办?
编辑:更多详情:
我正在将一种图像文件格式转换为TIFF文件.问题是起始文件格式可以是任何大小,但我需要将TIFF中的数据写入小端.所以我正在阅读我最终将打印到TIFF文件的内容首先打印到ByteBuffer中,这样我就可以将所有内容放入Little Endian,然后我将其写入outfile.我想因为我知道IFD有多长,标题是,我可以弄清楚每个图像平面中有多少字节,我可以在整个过程中使用多个ByteBuffers.
我有一个一维的String数组,我想转换成一维字节数组.我该怎么做呢?这需要ByteBuffer吗?我怎样才能做到这一点?(字符串可以是任意长度,只是想知道如何进行这样的操作.在将它转换为字节数组后,我怎么能将它转换回String数组?
-担
到目前为止,我能够设置MediaCodec来编码视频流.目的是将用户生成的图稿保存到视频文件中.
我使用用户图稿的android Bitmap对象将帧推送到流中.
请参阅我在本文底部使用的代码片段(它是完整的代码,没有任何修剪):
MediaCodec使用ByteBuffer处理视频/音频流.
位图基于int [],如果转换为byte []将需要x4 int []的大小
我做了一些研究,以确定在处理MediaCodec中的视频/音频流时ByteBuffer的合同是什么,但信息几乎接近于zilch.
那么,MediaCodec中的ByteBuffer使用合约是什么?
在MediaFormat中指定帧尺寸是否自动意味着ByteBuffers具有宽度*高度*4字节容量?
(我每帧都使用一个位图对象)
谢谢你的帮助.
(已编辑,已添加代码)
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import android.graphics.Rect;
import android.graphics.Bitmap.CompressFormat;
import android.media.MediaCodec;
import android.media.MediaCodec.BufferInfo;
import android.media.CamcorderProfile;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.util.Log;
import android.view.View;
public class VideoCaptureManager {
private boolean running;
private long presentationTime;
public void start(View rootView, String saveFilePath){
Log.e("OUT", saveFilePath);
this.running = true;
this.presentationTime = 0;
this.capture(rootView, saveFilePath);
}
private void capture(final View rootView, String saveFilePath){
if(rootView != …Run Code Online (Sandbox Code Playgroud) 我需要将bytearray转换为double.我在用
double dvalue = ByteBuffer.wrap(value).getDouble();
Run Code Online (Sandbox Code Playgroud)
但是在运行时我得到了BufferUnderflowException异常
Exception in thread "main" java.nio.BufferUnderflowException
at java.nio.Buffer.nextGetIndex(Buffer.java:498)
at java.nio.HeapByteBuffer.getDouble(HeapByteBuffer.java:508)
at Myclass.main(Myclass.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.hadoop.util.RunJar.main(RunJar.java:212)
Run Code Online (Sandbox Code Playgroud)
我需要在这里更改什么?
我理解当分配一个directbytebuffer时,它不受垃圾收集的影响,但我想知道的是包装对象是否被垃圾收集.
例如,如果我分配了一个新的DirectByteBuffer dbb,然后使用dbb.duplicate()复制(浅层复制)它,我会在同一块内存中有两个包装器.
这些包装纸是否需要进行垃圾收集?如果我做了
while(true){
DirectByteBuffer dbb2 = dbb.duplicate();
}
Run Code Online (Sandbox Code Playgroud)
我最终会自己OOM吗?
我有第三方C++库,其中一些类方法使用原始字节缓冲区.我不太确定如何处理Boost :: Python.
C++库头类似于:
class CSomeClass
{
public:
int load( unsigned char *& pInBufferData, int & iInBufferSize );
int save( unsigned char *& pOutBufferData, int & iOutBufferSize );
}
Run Code Online (Sandbox Code Playgroud)
坚持使用Boost :: Python代码......
class_<CSomeClass>("CSomeClass", init<>())
.def("load", &CSomeClass::load, (args(/* what do I put here??? */)))
.def("save", &CSomeClass::save, (args(/* what do I put here??? */)))
Run Code Online (Sandbox Code Playgroud)
如何将这些原始缓冲区包装在Python中作为原始字符串公开?
背景
假设我有一个直接的ByteBuffer:
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
Run Code Online (Sandbox Code Playgroud)
并假设我将缓冲区传递给AsynchronousSocketChannel以从该套接字读取数据块,一次最多X个字节(此处示例中为1024).
从套接字到直接 ByteBuffer 的传输时间非常棒,因为它全部发生在本机OS内存空间中; 我还没有通过JVM"血脑"屏障......
题
假设我的工作是扫描从直接字节缓冲区读回的所有字节,我这样做的最快方法是什么?
我最初问" ......利用sun.misc.Unsafe "但也许这是错误的假设.
可能的方法
我目前看到三种方法,我最感兴趣的是#3:
我确实认为,假设copyMemory操作正是它所宣传的内容,即使在更优的操作系统空间中,上面的#2方法可能仍然是最优化的,因为我没有在开始处理之前创建缓冲区的重复项它.
这与" 我可以使用不安全迭代字节[]更快吗? "问题不同,因为我甚至没有计划在内部将字节拉入字节[],如果没有必要的话.
谢谢你的时间; 只是好奇,如果有人(彼得?)已经疯狂与不安全做这样的事情.