gpt4 book ai didi

java - 如何在java中使用Linux mincore()

转载 作者:行者123 更新时间:2023-12-02 02:58:58 27 4
gpt4 key购买 nike

在java中,如何查找驻留在文件内存中的页面。

我在C库中找到了mincore(),mincore - 确定页面是否驻留在内存中

如何使用java查找内存中文件的页面?

最佳答案

需要使用JNI或JNA来调用mincore。使用普通的 Java 是不可能的。

您只能在内存映射文件上使用 mincore。

有一个library这是通过 JNI 实现的。我用过JNA在为个人项目使用内存映射文件时。我添加了 JNA 代码,以便为您提供更好的想法。

您可以使用漂亮的vmtouch程序来仔细检查结果。

import com.sun.jna.*;
import sun.misc.Unsafe;
import sun.nio.ch.FileChannelImpl;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
* Example how to access mincore function from Java.
*/
public class MincoreJava {

public static void main(String[] args) throws Exception {

String file = "/tmp/foo.test";

FileChannel fc = FileChannel.open(Paths.get(file), StandardOpenOption.WRITE, StandardOpenOption.READ);

// calls mmap
MappedByteBuffer mmaped = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size());

// play with this to see how it changes the output
mmaped.put(10*4*1024, (byte)2);

// first lets get the address of the mmap file
// we can do this with plain Java reflection
long nativeAddress = getNativeAddressOf(mmaped);

// before we call the mincore we should get the value of system page size
// we can do this with reflection
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null);
int PAGE_SIZE = unsafe.pageSize();

// we need to prepare the vec array that will hold the results
// the vec must point to an array containing at least (length+PAGE_SIZE-1) / PAGE_SIZE bytes
int pages = (int) ((fc.size() + (PAGE_SIZE - 1)) / (PAGE_SIZE));
byte[] vec = new byte[pages];

// do the mincore call using JNA (we could just as well used JNI)
int result = CLibray.INSTANCE.mincore(nativeAddress, fc.size(), vec);

if (result != 0) {
throw new RuntimeException("Call to mincore failed with return value " + result);
}

// print out the pages
System.out.println("File: " + file);
System.out.println("\nOccupies " + fc.size() + " Bytes and " + pages + " Pages");

printPageInfo(nativeAddress, PAGE_SIZE, vec);

// we can call munmap via reflection
unmap(mmaped);
}

// This is the idiomatic JNA way of dealing with native code
// it is also possible to use native JNA methods
// and alternatively JNI
public interface CLibray extends Library {
CLibray INSTANCE = (CLibray) Native.loadLibrary("c", CLibray.class);

// int mincore(void *addr, size_t length, unsigned char *vec);
// JNA will automagically convert the parameters to native parameters
int mincore(long addr, long length, byte[] vec);
}

private static void printPageInfo(long baseAddress, int PAGE_SIZE, byte[] vec) {
for (int i = 0; i < vec.length; i++) {
// the least significant bit is 1 if paged
String paged = Integer.toBinaryString(vec[i]);

System.out.println(String.format("Page_%06d_[0x%s-0x%s]_%s", i,
Long.toHexString(baseAddress + i * PAGE_SIZE),
Long.toHexString(baseAddress + i * PAGE_SIZE + PAGE_SIZE - 1),
paged));
}
}

private static long getNativeAddressOf(ByteBuffer map) throws Exception {
final Field field = Buffer.class.getDeclaredField("address");

field.setAccessible(true);
return field.getLong(map);
}

public static void unmap(final MappedByteBuffer buffer) throws Exception {
if (null != buffer) {
final Method method = FileChannelImpl.class.getDeclaredMethod("unmap", MappedByteBuffer.class);

method.setAccessible(true);
method.invoke(null, buffer);
}
}
}

关于java - 如何在java中使用Linux mincore(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24485109/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com