在JNI客户端应用程序中设置较小的JVM堆大小

时间:2012-09-13 11:26:13

标签: java postgresql jvm

我正在尝试使用pl / java调试问题,这是PostgreSQL的一种过程语言。我正在Linux服务器上运行这个堆栈。

基本上,每个Postgres后端(连接进程)必须启动自己的JVM,并使用JNI执行此操作。这通常是pl / java的一个主要限制,但它有一个特别令人讨厌的表现。

如果本机内存耗尽(我意识到这可能实际上不是由于malloc()返回NULL,但效果大致相同),这种失败的处理相当差。由于“本机内存耗尽”,它导致OutOfMemoryError。这导致Postgres后端的段错误,源自libjvm.so,以及一个javacore文件,其中包含:

0SECTION       TITLE subcomponent dump routine
NULL           ===============================
1TISIGINFO     Dump Event "systhrow" (00040000) Detail "java/lang/OutOfMemoryError" "Failed to create a thread: retVal -1073741830, errno 11" received
1TIDATETIME    Date:                 2012/09/13 at 16:36:01
1TIFILENAME    Javacore filename:    /var/lib/PostgreSQL/9.1/data/javacore.20120913.104611.24742.0002.txt
***SNIP***

现在,有一些相当明确的方法来改善Java的这些类型的问题,如下所述:

http://www.ibm.com/developerworks/java/library/j-nativememory-linux/

我认为如果我可以将最大堆大小设置为远低于默认值的值,那将会特别有效。通常,可以按照以下方式做一些事情:

  

使用-Xmx和-Xms选项从Java命令行控制堆的大小(mx是堆的最大大小,ms是初始大小)。虽然逻辑堆(主动使用的内存区域)可以根据堆上的对象数量和GC中花费的时间量来增长和缩小,但是使用的本机内存量保持不变,并且由 - Xmx值:最大堆大小。大多数GC算法依赖于堆被分配为连续的内存块,因此当堆需要扩展时,不可能分配更多的本机内存。所有堆内存必须预先保留。

然而,我不知道如何遵循这些步骤,以便pl / java的JNI初始化初始化具有较小堆的JVM;我不能很好地将这些命令行参数传递给Postgres。所以,我的问题是,如何在这种情况下设置最大堆大小或以其他方式控制这些问题?这似乎是pl / java的一般问题,所以我希望能够分享我最终与Postgres社区达成的解决方案。

请注意,我没有JVM内部经验,也不熟悉Java。

由于

1 个答案:

答案 0 :(得分:1)

根据slide 19 in this presentation postgresql.conf可以使用参数pljava.vmoptions,您可以在其中将参数传递给JVM。