减少Solaris上多个Java进程的内存占用(UNIX)

时间:2011-02-10 21:38:19

标签: java memory process fork shared-memory

有没有办法让Java进程分叉或启动另一个Java进程并使用共享内存以最小化RAM使用?

为了在不影响其他人的情况下安全地杀死一个进程,将会有许多进程。此外,这将允许简单检测哪些线程使用更多内存或CPU(如果它们位于不同的进程中)。这应该允许任何进程发生崩溃或OutOfMemoryError而不影响其他进程。

如果我们可以同时运行100-300个java进程,每个进程都有自己的用途,那就太好了。我意识到,如果我们要避免从数据库和文件系统中抢走太多内存,我们可能必须限制该数量并要求进程承担多个角色。

修改
当我说共享内存时,我想我的意思不正确。我的意思是只能在Java类(而不是变量)之类的多个进程中使用的内存。如果可能,可以重用所有java包和库。

3 个答案:

答案 0 :(得分:0)

共享内存是什么意思?你在谈论主机系统的内存吗?

由于您使用的是Solaris,因此Java线程是Solaris线程,每个线程都有自己的进程。但Java仍然在您提供的JVM内存参数下运行。如果出现OutOfMemoryError,则JVM的内存池已达到其限制,而不是主机系统。换句话说,在Java中,您永远不会真正访问共享内存 - 这就是JVM的工作。如果Java进程需要更多内存,则必须提高JVM的内存限制。但是所有内存都由JVM管理。为了真正访问共享内存,您需要使用JNI离开JVM并进入主机内存。

如果您正在讨论JVM启动另一个JVM,我认为这是可能的,但是您正在讨论多个JVM,并且为了最大限度地减少RAM使用,应该为每个JVM提供一个非常小的初始内存池来处理。否则,你有一堆JVM占用了他们的虚拟内存模型以及相关线程的内存。

答案 1 :(得分:0)

不,据我所知,这是不可能的。这有几个原因:

  1. 共享对象的所有权将是一个可疑的事情,因此每线程内存限制将无法执行。
  2. 如果一个线程死了,这是一个严重的问题。线程不会像这样意外死亡,而不是你安装了一个catch-all异常处理程序。线程在编写良好的系统中无意中死亡的唯一原因是,如果抛出Error,这意味着系统不稳定,通常也意味着应该尽快停止VM。
  3. 除了一些非常特殊的情况(尤其是应用程序/ web服务器)任何系统都不可能在丢失其中一个线程后继续运行。这往往会产生可怕的后果。
  4. 更新:发现它是一个网络服务器需要一个解决方案,我会尝试更进一步。尽管Java并不是为了您所需的高度隔离而设计的。某些功能可以由JVMTI代理实现。具体来说,线程可以是stoppedobjects reachable by a thread can be checkedquery the time used up by each thread等等。坏消息是你的代理必须用C或类似的东西编写,众所周知很难调试,任何错误都可能导致虚拟机崩溃。

答案 2 :(得分:0)

@George Baily - 刚刚在上面发表了你的评论。

是的,较新的JVM确实共享类文本,但据我所知只在客户端(非服务器)JVM中。这样做的好处是减少了IO和启动时间,但在帮助缩小占用空间方面具有额外的好处。

您可以在这里阅读更多内容:

http://download.oracle.com/javase/1.5.0/docs/guide/vm/class-data-sharing.html

您可能还希望对堆调整大小参数采取积极措施,以允许更小的占用空间。虽然是半商业化的,但我维护了一个小软件包来管理多个(数百个)JVM的工作负载,并动态管理操作系统级IO和进程优先级以满足工作负载目标。一个穷人的JVM WLM。因为能够在运行时管理JVM人体工程学,我一直没有成功,但是WLM方法的效果非常好。如果您想了解更多信息,请与我们联系。