java为什么内存会无限增大_Java进程的内存无限增长,但是MemoryMXBean报告稳定堆和非堆大小...

我正在与一个开发在1GB

Linux目标系统上运行的Java GUI应用程序的团队合作.

我们有一个问题,我们的java进程使用的内存无限期地增长,直到Linux终于杀死了java进程.

我们的堆内存健康稳定. (我们广泛地分析了我们的堆)我们还使用MemoryMXBean监视应用程序的非堆内存使用情况,因为我们认为问题可能在这里.但是,我们看到的报告的堆大小报告的非堆大小保持稳定.

以下是使用1GB RAM(由MemoryMXBean报告的堆和非堆,使用Linux的顶级命令(驻留内存)监视的Java进程使用的总内存))在目标系统上运行应用程序时的数字的示例.

在启动时:

> 200 MB堆提交

> 40 MB非堆提交

> java进程使用320 MB

1天后:

> 200 MB堆提交

> 40 MB非堆提交

> java进程使用的360 MB

2天后:

> 200 MB堆提交

> 40 MB非堆提交

> java进程使用的400 MB

上面的数字只是我们系统执行的“更干净”的代表,但它们是相当准确和接近现实的.正如你所看到的,趋势是明确的.运行应用程序几周后,由于系统内存不足,Linux系统开始出现问题.事情开始放缓.再过几个小时之后,Java进程就被杀死了.

经过几个月的分析,并试图弄清楚这一点,我们仍然在亏损.我觉得很难找到关于这个问题的信息,因为大多数讨论最终解释堆或其他非堆内存池. (如Metaspace等)

我的问题如下:

>如果你打破它,java进程使用的内存包括什么? (除堆和非堆内存池之外)

>哪些其他潜在的来源有内存泄漏? (本机代码?JVM开销?)哪些是一般的,最可能的罪魁祸首?

>如何一个监视器/配置文件这个内存?堆堆之外的所有东西目前对我们来说都是一个黑匣子.

任何帮助将不胜感激.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java虚拟机的各内存区域名称是: 1. 程序计数器(Program Counter Register) 2. Java虚拟机栈(Java Virtual Machine Stacks) 3. 本地方法栈(Native Method Stacks) 4. Java堆(Java Heap) 5. 方法区(Method Area) 6. 运行时常量池(Runtime Constant Pool) 7. 直接内存(Direct Memory) 要编程获取各内存区域的最大空间和可用空间,可以使用JMX(Java Management Extensions)来监控Java虚拟机的内存使用情况。以下是一个示例代码片段,可以用来获取Java堆的最大空间和可用空间: ``` import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; import java.lang.management.MemoryUsage; public class MemoryMonitor { public static void main(String[] args) { MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean(); MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage(); long maxHeapSize = heapMemoryUsage.getMax(); long usedHeapSize = heapMemoryUsage.getUsed(); System.out.println("Max Heap Size = " + (maxHeapSize / (1024*1024)) + " MB"); System.out.println("Used Heap Size = " + (usedHeapSize / (1024*1024)) + " MB"); } } ``` 这个示例代码输出Java堆的最大空间和可用空间,单位为MB。其他内存区域的最大空间和可用空间可以使用类似的方式获取。 ### 回答2: Java虚拟机(JVM)中主要有以下几个内存区域: 1. 方法区(Method Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。可以通过运行时常量池来转存一部分常量池数据到堆中。 2. 堆(Heap):用于存储对象实例。堆被所有线程共享,在JVM启动时创建。堆的大小可以通过-Xmx和-Xms参数来调整,分别表示最大堆空间和初始堆空间。 3. 栈(Stack):每个线程都有一个独立的栈,用于存储局部变量、方法参数等。每个方法在调用时创建一个栈帧,当方法执行完毕后栈帧被销毁。栈的大小可以通过-Xss参数来调整。 4. 本地方法栈(Native Method Stack):用于执行本地方法(由其他语言编写的方法)的栈。 5. PC寄存器(Program Counter Register):存储当前线程执行的JVM指令地址。 编程获取各内存区域的最大空间和可用空间有不同的方法: 1. 方法区和本地方法栈内存区域的最大空间和可用空间一般是固定的,并可以通过JVM参数进行调整。 2. 堆内存区域的最大空间和可用空间可以通过Java代码获取。可以通过Runtime类的totalMemory()方法获取堆的总大小,通过freeMemory()方法获取堆的可用空间。 3. 栈内存区域的最大空间和可用空间是由操作系统限制的,一般不需要手动调整。可以通过Thread类的getStackSize()方法获取栈的大小,但是没有直接的方法获取栈的可用空间。 综上所述,不同的内存区域的最大空间和可用空间获取方法有所差别,需要根据具体的区域进行处理。 ### 回答3: 在JAVA虚拟机中,内存被划分为以下几个区域: 1. 堆(heap):堆是JAVA虚拟机管理的最大的内存区域,用于存放对象的实例和数组。可以通过调整-Xmx和-Xms参数来设置堆的最大和初始大小。 2. 方法区(method area):方法区用于存储类的元数据,包括类的信息、常量、静态变量等。在JDK 7及之前,方法区被实现为永久代(Permanent Generation);而在JDK 8及之后,方法区被实现为元空间(Metaspace)。 3. 虚拟机栈(stack):虚拟机栈用于存放方法的执行过程中的局部变量、方法参数、返回值等。每个线程在执行方法时,都有一个对应的栈帧(stack frame)用于保存方法的信息。可以通过调整-Xss参数来设置每个线程的栈大小。 4. 本地方法栈(Native Method Stack):本地方法栈与虚拟机栈类似,用于存放JNI(Java Native Interface)方法的信息。 5. 程序计数器(Program Counter):程序计数器是一块较小的内存区域,用于存放当前线程执行的字节码指令的地址。 编程获取各内存区域的最大空间和可用空间,可以使用JAVA虚拟机提供的ManagementFactory和MemoryMXBean类来实现。通过MemoryMXBean的getHeapMemoryUsage()方法可以获取堆内存区域的使用情况,包括最大空间和当前已使用空间。而通过ManagementFactory的getMemoryPoolMXBeans()方法可以获取所有内存池的信息,然后可以通过MemoryPoolMXBean的getUsage()方法获取各内存池的使用情况,包括最大空间和当前已使用空间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值