Syn*_*r0r 23 java garbage-collection jvmti
我不是在寻找通常的"你只能使用System.gc()来回答Java中的GC ",这个问题根本不是什么.
我的问题不是主观的,而是基于现实:GC 可以用Java来强制实现.我们每天使用的许多程序都是这样做的:IntelliJ IDEA,NetBeans,VisualVM.
它们都可以强制 GC发生.
怎么做?
我认为他们都使用JVMTI,更具体地说是ForceGarbageCollection(注意"Force"),但我怎么能为自己尝试呢?
http://java.sun.com/javase/6/docs/platform/jvmti/jvmti.html#ForceGarbageCollection
还要注意,这个问题不是关于"为什么"我想要这样做:"为什么"可能是"好奇心"或"我们正在编写类似于VisualVM的程序"等.
问题是"你如何使用JVMTI的ForceGarbageCollection强制GC"?
是否需要使用任何特殊参数启动JVM?
是否需要任何JNI?如果是这样,究竟是什么代码?
它只适用于Sun VM吗?
任何完整和可编辑的例子都是最受欢迎的.
小智 10
NetBeans,至少使用System.gc():http://hg.netbeans.org/main/annotate/9779f138a9c9/openide.actions/src/org/openide/actions/GarbageCollectAction.java(这是用于小按钮)显示当前堆并允许您启动GC).如果您遵循该链接,您将看到他们明确地运行终结器.如果您有一些免费的磁盘空间,并且想要自己调查代码,可以通过Mercurial获取:hg clone http://hg.netbeans.org/main/
据我所知,"System.gc()只是一个提示"的教条起源于对JLS和JVM规范的迂腐解释,它允许Java实现没有垃圾收集堆.那,以及对JavaDoc的不完整阅读:
调用gc方法表明Java虚拟机花费了大量精力来回收未使用的对象,以使其当前占用的内存可用于快速重用.当控制从方法调用返回时,Java虚拟机已尽最大努力从所有丢弃的对象中回收空间.
阅读第二句话:"尽力回收空间"比"提示"强很多.
也就是说,很少有理由打电话System.gc().向Knuth道歉:
我们应该忘记内存管理,大约97%的时间说:显式垃圾收集是所有邪恶的根源
我构建了一个基本的 java 代理,允许调用 jvmtiForceGarbageCollection函数:
#include <stdlib.h>
#include <stdio.h>
#include <jvmti.h>
typedef struct {
jvmtiEnv *jvmti;
} GlobalAgentData;
static GlobalAgentData *gdata;
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved)
{
printf("load garbager agent\n");
jvmtiEnv *jvmti = NULL;
// put a jvmtiEnv instance at jvmti.
jint result = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);
if (result != JNI_OK) {
printf("ERROR: Unable to access JVMTI!\n");
}
// store jvmti in a global data
gdata = (GlobalAgentData*) malloc(sizeof(GlobalAgentData));
gdata->jvmti = jvmti;
return JNI_OK;
}
extern "C"
JNIEXPORT void JNICALL Java_Garbager_forceGarbageCollection(JNIEnv *env, jclass thisClass)
{
printf("force garbage collection\n");
gdata->jvmti->ForceGarbageCollection();
}
Run Code Online (Sandbox Code Playgroud)
该代理通过JNI调用:
class Garbager {
public static void main(String[] args) {
Garbager.garbageMemory();
}
static void garbageMemory() {
forceGarbageCollection();
}
private static native void forceGarbageCollection();
}
Run Code Online (Sandbox Code Playgroud)
要在 MacOSX 上编译代理:
clang -shared -undefined dynamic_lookup -o garbager-agent.so -I /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/include/ -I /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/include/darwin garbager-agent.cpp
Run Code Online (Sandbox Code Playgroud)
启动Garbager:
java -agentpath:garbager-agent.so Garbager
Run Code Online (Sandbox Code Playgroud)
基于本教程:拥有你的堆:使用 JVMTI 迭代类实例
| 归档时间: |
|
| 查看次数: |
5346 次 |
| 最近记录: |