我正在努力将Perl程序移植到Java,并且随时学习Java.原始程序的核心组件是Perl模块,它使用二进制搜索在+500 GB排序文本文件中执行字符串前缀查找(实质上,"搜索"到文件中间的字节偏移,回溯到最近的换行,比较带有搜索字符串的行前缀,"seek"到那个字节偏移的一半/两倍,重复直到找到...)
我已经尝试了几种数据库解决方案,但发现没有什么比这个大小的数据集纯粹的查找速度更好.您知道任何实现此类功能的现有Java库吗?如果做不到这一点,你能指出一些在文本文件中进行随机访问读取的惯用示例代码吗?
或者,我不熟悉新的(?)Java I/O库,但它是一个内存映射500 GB文本文件的选项(我在64位机器上,内存备用)并做二进制文件搜索内存映射的字节数组?我很想知道你必须分享的关于这个和类似问题的任何经验.
假设 C++ 编译器为 CPU 寄存器未进行内存映射的体系结构编译了代码。并且假设同一个编译器为 CPU 寄存器保留了一些指针值。
例如,如果编译器无论出于何种原因(例如优化原因),为变量使用寄存器分配(不是谈论 register 关键字),并且我们打印对该变量的引用的值,编译器将返回其中一个保留的“地址值”。
该编译器会被视为符合标准吗?
从我所能收集到的(我还没有阅读整个事情 -工作草案,编程语言 C++ 标准),我怀疑该标准没有提到 RAM 内存或操作内存之类的东西,它定义了自己的内存模型相反,指针作为地址的表示(可能是错误的)。
现在由于寄存器也是一种内存形式,我可以想象将寄存器视为内存模型一部分的实现可能是合法的。
在运行Linux的基于ARM的系统上,我有一个内存映射到物理地址的设备.从所有地址都是虚拟的用户空间程序,我如何从该地址读取内容?
我最近发现Linux不保证分配的内存mmap可以释放,munmap如果这导致VMA(虚拟内存区域)结构数超过的情况vm.max_map_count.Manpage(几乎)清楚地说明了这一点:
ENOMEM The process's maximum number of mappings would have been exceeded.
This error can also occur for munmap(), when unmapping a region
in the middle of an existing mapping, since this results in two
smaller mappings on either side of the region being unmapped.
Run Code Online (Sandbox Code Playgroud)
问题是Linux内核总是尝试合并VMA结构,munmap即使对于单独创建的映射也会失败.我能够编写一个小程序来确认这种行为:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>
// value of vm.max_map_count
#define VM_MAX_MAP_COUNT (65530)
// number of vma for the empty process linked against libc …Run Code Online (Sandbox Code Playgroud) 我刚刚注意到我的简单程序的数据和堆栈段是可执行的.我在/ proc/[pid]/maps中看到了它,简单的代码证实了它.
例如:
; prog.asm
section .data
code: db 0xCC ;int3
section .text
global _start
_start:
jmp code
mov rax, 60 ; sys_exit
mov rdi, 0
syscall
Run Code Online (Sandbox Code Playgroud)
然后
nasm -f elf64 prog.asm
ld -o prog prog.o
./prog
Run Code Online (Sandbox Code Playgroud)
导致prog执行int3指令.
用C语言编写并用gcc构建的程序使其数据,堆栈和堆不可执行,那么为什么那些用汇编编写的程序会以不同的方式运行?
任何人都可以解释一下copy_from_user函数究竟是如何在内部工作的吗?它是否使用任何缓冲区,或者考虑到内核确实有权访问用户空间mem这一事实,是否有任何内存映射.
所以我在Gamasutra上阅读了John Carmack的采访,其中他谈到了他所谓的"生活在内存映射文件中的实时C++对象".以下是一些引用:
JC:是的.我实际上从中获得了多项好处...最后一个iOS Rage项目,我们附带了一些新技术,这些技术使用一些聪明的东西来制作生活在内存映射文件中的实时C++对象,由闪存文件系统支持在这里,我想要构建我们未来在PC上的所有工作.
...
我在这里向自己发出命令,我希望在我们的PC平台上加载两秒钟的游戏,所以我们可以更快地迭代.而现在,即使固态硬盘,你所有你在加载时间做的事情为主,所以需要这种不同学科可以说"一切都将被毁灭和相对地址使用"所以你只要说,"映射文件,我的所有资源都在那里,它在15毫秒内完成."
(完整的采访可以在这里找到)
有没有人知道Carmack在谈论什么以及你将如何设置这样的东西?我在网上搜索了一下,但我似乎无法找到任何相关信息.
我正在阅读"现代操作系统"一书.我对"页面大小"感到困惑.
在这本书中,作者说,
传入的16位虚拟地址分为4位页码和12位偏移量.对于页码,有4位,我们可以有16页,并且对于偏移有12位,我们可以寻址页面中的所有4096 个字节.
为什么4096字节?使用12位,我们可以在页面内处理4096个条目,这是正确的.但是,一个条目是一个地址(在这种情况下,地址大小= 16位).所以我认为我们可以解决4096(条目)*16(位)= 4096(条目)*2(字节)= 8KB,但为什么书中说我们可以解决4096(字节)?
提前致谢!:)
operating-system memory-management virtual-memory memory-mapping
通常可以说:如何byte[] get(offset, length)为Java中大于2GB的内存映射文件实现一种方法.
有了上下文:
我正在尝试使用随机i/o高效读取大于2GB的文件.当然,这个想法是使用Java nio和内存映射API.
问题是内存映射限制为2GB.其中一个解决方案是映射多个2GB的页面并通过偏移量进行索引.
这里有一个类似的解决方案:
这个解决方案的问题在于它设计为在我的API应该读取时读取字节byte[](因此我的API就像这样read(offset, length)).
是否只是努力将这种终极get()变为get(offset, length)?当byte[]我在阅读两页之间时会发生什么?
mmap调用的效果是原子的吗?
也就是说,对mmap访问受影响区域的其他线程而言,由 所做的映射更改是否以原子方式出现?
作为试金石,请考虑您mmap在一个全为零的文件中执行 a 的情况(来自线程T1,这是此时唯一的线程),然后开始从该区域读取的第二个线程T2。然后,再次在 T1(原始线程)上mmap对同一区域进行第二次调用,将映射替换为针对所有 1 的文件的新映射。
是否有可能为读者线程读取一些页面一(即,见第二mmap的效果),然后随后从一些页面读取零(即,见效果的第一个映射)?
您可以假设读取器线程上的读取已被正确隔离,即上述效果不仅仅由于 CPU/一致性级别的内存访问重新排序而发生。
memory-mapping ×10
linux ×5
c++ ×2
java ×2
mmap ×2
nio ×2
arm ×1
assembly ×1
concurrency ×1
enomem ×1
io ×1
large-files ×1
linux-kernel ×1
memory ×1
nasm ×1
performance ×1
posix ×1