首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JVM内存使用情况,有线程的JVM,还是我的四个应用程序中的四个JVM?

JVM内存使用情况,有线程的JVM,还是我的四个应用程序中的四个JVM?
EN

Stack Overflow用户
提问于 2012-06-12 19:06:50
回答 2查看 607关注 0票数 1

目前,我有四个不同的java应用程序,这些应用程序由..bat启动的jars运行,这些文件放在Windows嵌入式开始菜单中的starup文件夹中。我还启动了Firefox。现在火狐或者其中一个Java应用程序刚刚关闭。我猜我内存用完了(Win XP嵌入512 MB内存)。

四个Java应用程序是,

  • 人机界面后端(用星火“微”框架构建)
  • 是一个记录器应用程序,它将来自PLC的数据记录到H2数据库。这是通过使用Timer/Timertask
  • The h2数据库服务器
  • A调度程序执行定期作业来实现的。使用Quartz.

因此,这些Java应用程序都是在自己的JVM中启动的(据我所知)。第一个问题是:我可以通过在一个JVM而不是四个JVM中运行这四个应用程序来降低它们的内存使用量吗?如果是这样的话,我应该使用线程来启动每个应用程序吗?

除此之外,我应该做的第一件基本的事情是降低内存占用,这对于“真正的”Java编程来说是非常新的H2连接池、重用对象以及其他什么?J控制台和Xmx之类的东西?

可能很天真,但我真的认为,嘿,GC会照顾我的“一切”。你猜不是吗?

编辑:人机界面后端使用Jetty服务器。而且,所有的代码要么是开源的,要么是由我构建的。

编辑2: Web:http://www.sparkjava.com/。我是通过框架服务静态媒体,而不是通过Jetty (jetty 7.3)。这可能是用来改善内存使用的东西吗?HMI应用程序的其他组件包括共济会模板引擎、gson、servlet 3、slf4j和log4j。

也许在启动webapp时尝试在线程中启动记录器和调度程序是可能的。然后只运行两个JVM。一个用于webapp,另一个用于数据库服务器。

我使用的是Java 7,它是一个32位系统。它有望用于生产(否则我就有麻烦了)。

EN

回答 2

Stack Overflow用户

发布于 2012-06-12 19:31:45

从一组单独的进程到单个进程通常不仅仅是“翻转开关”的问题。它们是根本不同的架构:

属于manner;

  • different相同进程
  • 线程共享某些资源(内存空间、文件句柄等),它们可以在彼此之间“看到”;它们可以在非常“轻量级”的进程中相互通信和共享数据,它们在某种程度上是更“孤立的”单元:它们不能只是“窥视”对方的内存、文件句柄等,而是必须以“更重”的方式(例如,通过操作系统提供的套接字或其他设施)进行通信。

现在,你能从一个模型移动到另一个模型有多容易,它会给你买多少钱,这真的取决于特定的组件正在做什么以及它们是如何交互的。我不熟悉您提到的一些组件,但从您的描述中可以看出,您实际上拥有一堆相互关联的“黑匣子”,您将无法进行大量的重新架构。

因此,我建议查看各种组件的文档,看看它们是否允许您在启动时指定VM大小(或“堆大小”),然后尝试将组件降到它们所需的最小值。(你的记录器过程大概不需要几百兆字节.)

原则上,Windows不应该“关闭一个进程,因为它耗尽了内存”。如果它需要交换JVM在虚拟内存中和从虚拟内存中堆出的部分,那么它可能会像地狱一样开始发出咕噜声。但它不应该真正关闭进程。另一方面,如果一个给定的Java应用程序在尝试从其堆中分配内存时获得一个OutOfMemoryError,它可能会决定关闭(或者根据其异常处理而作为默认行为关闭)。各个组件的日志显示发生了什么?

*与本机应用程序不同,Java应用程序不能很好地处理虚拟内存,因为对Java来说,它的内存是一个单独的“堆”,它实际上希望总是在其中分页。您应该避免为JVM分配堆大小,因为它接近或大于机器中的物理内存量。

票数 4
EN

Stack Overflow用户

发布于 2012-06-12 23:52:47

我故意不讨论尼尔·科菲的回答已经涵盖的方面。

因此,每个

应用程序都是在自己的JVM中启动的(据我所知)。第一个问题是:我可以通过在一个JVM而不是四个JVM中运行这四个应用程序来降低它们的内存使用量吗?如果是这样的话,我应该使用线程来启动每个应用程序吗?

不,或者不容易(见尼尔·科菲的回答)。

但是您可以通过向.bat程序传递命令行参数来调整每个java.exe的java内存设置。

考虑到您有相当有限的内存设置,并且假设您至少有JavaSE6Update 10,我建议您尝试G1垃圾收集器,在内存设置相对较低的情况下,可以使用它获得良好的性能。

也许可以尝试通过类似的内容,并在需要时进行调整:

代码语言:javascript
复制
-Xss64k -Xms128m -Xmx128m -XX:PermSize=64m -XX:MaxPermSize=64m -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:+UseCompressedStrings -XX:+UseCompressedOops

请注意,-XX:+UseCompressedStrings)只适用于x64 JVM,而且它(以及x64)可能不适用于您,这取决于您的JVM版本。而且,你也不会说它是用于生产还是用于个人用途。如果用于生产,我建议您不要使用这2,只需使用-XX:+UseG1GC`即可。

当我需要在一台机器上运行Eclipse的多个实例时,需要用2GB的RAM构建更大的项目时,上述设置是我使用的设置的一个变体。不幸的是,你的环境有点硬,但是试着一次使用这个应用程序,看看你能压缩和适应多少。

如果可以的话,给我们更多关于你的进程正在做什么的信息,这样我们就可以试着评估他们需要多少内存。可能,您可以更多地减少堆栈大小和堆大小。我们知道的越多,在调整设置时,在黑暗中点击的次数就越少。

除此之外,我应该做的第一件基本的事情是降低内存占用,这对于“真正的”

编程来说是非常新的H2连接池、重用对象以及其他什么?J控制台和Xmx之类的东西?

H2已经相当轻量级,听起来是个不错的选择。

JConsole不会帮助您,但是您可能想尝试一下JVisualVM,它可以帮助分析一些事情。或者瞄准JProfiler,如果你能负担得起的话。否则,Eclipse有一个很好的内存分析器。

可能很天真,但我真的认为,GC会为我处理“一切”。你猜不是吗?

这不是魔法,它只是回收未使用的物品。如果你有它们的引用,它就不知道你是否需要它们。因此,要么确保引用不保持活动(通常通过保持集合或相互链接的复合对象),要么如果您需要长时间的引用,可以查看弱引用或软引用(或者在缓存实现中)。

编辑:人机界面后端使用Jetty服务器。而且,所有的代码要么是开源的,要么是由我构建的。

给我们更多的细节,我们可以进一步挖掘。

您可以做的另一件事是查看其他JVM。嵌入式系统中也有一些,它们显然具有相当有限的环境。

根据调度作业的复杂性,您可以推出自己的调度程序,而不需要依赖Quartz。它不是特别的重量级,但如果您需要挤压每一个MB,这将是您的列表中的第一个元素,我将尝试删除。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11003167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档