【问题标题】:Reducing the memory footprint of multiple Java processes on Solaris (UNIX)减少 Solaris (UNIX) 上多个 Java 进程的内存占用
【发布时间】:2011-06-25 04:23:55
【问题描述】:

有没有办法让 Java 进程派生或启动另一个 Java 进程并使用共享内存以最大限度地减少 RAM 使用?

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

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

编辑:
当我说共享内存时,我认为我的意思不正确。我的意思只是可以在多个进程之间使用的内存,比如 Java 类(而不是变量)。如果可能,所有的 java 包和库都可以重用。

【问题讨论】:

标签: java memory process fork shared-memory


【解决方案1】:

@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 方法的效果出奇的好。如果您想了解更多信息,请告诉我。

【讨论】:

  • 按照文档,它使用 server JVM 中的 -Xshare:dump 生成共享存档 (classes.jsa)
【解决方案2】:

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

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

如果你说的是一个 JVM 启动另一个 JVM,我想这是可能的,但是你说的是多个 JVM,为了最大限度地减少 RAM 使用,每个 JVM 都应该有一个非常小的初始内存池来使用.否则,您将有一堆 JVM 为其虚拟内存模型以及相关线程占用内存。

【讨论】:

  • 这是一个 JVM 启动另一个 JVM 的情况。我指的是 Java 核心或任何在父进程和子进程之间保持相同或最初相同但稍后如果需要更改某些段可能会被复制以处理特定空间的内容。我不知道我在说什么。我只是想尝试尽可能减少 RAM 的使用。我知道我将不得不锁定-Xmx 以保持合理。但是,MySQL 连接器、所有 java 包之类的类存储(不是变量); Java 邮件,PDF 生成器。这些通常会在多个进程中使用。
【解决方案3】:

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

  1. 共享对象的所有权将是一件可疑的事情,因此每个线程的内存限制将无法执行。
  2. 如果一个线程死掉,那就是一个严重的问题。线程不会像那样意外死亡,如果你安装了一个包罗万象的异常处理程序。在编写良好的系统中,线程意外死亡的唯一原因是如果抛出 Error,这意味着系统不稳定,通常还意味着应该尽快停止 VM。
  3. 除了一些非常特殊的情况(尤其是应用程序/网络服务器)任何系统都不太可能在失去一个线程后继续运行。这通常会产生可怕的后果。

更新:发现它是一个需要解决方案的网络服务器后,我会尝试更进一步。尽管 Java 的设计并不是为了达到您需要的隔离级别。一些功能可以通过JVMTI 代理来实现。具体来说,线程可以是stopped、objects reachable by a thread can be checked、query the time used up by each thread等。坏消息是你的代理必须用 C 或类似的语言编写,众所周知,它很难调试,任何错误都可能导致虚拟机崩溃。

【讨论】:

  • 这是一个 webapp 服务器。一些 webapp 在生产环境中会经常更改。因此,由于代码错误,不可避免地会出现无限循环和内存溢出。如果发生这种情况,它将必须与其余线程隔离 - 我希望这只能通过分离进程来完全实现。如有必要,具有无限循环的进程中的现有线程可以完成,并且网络服务器可以知道不应该在该进程上启动(请求)任何新线程。不要嘲笑我写了一个新的网络服务器。这是经过深思熟虑的。
  • @George Bailey 我为什么要笑?我会更新我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 2023-03-07
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多