Tag: 内存管理

是否有可能“看到”垃圾收集的对象图?

我有一个泄漏内存的Java应用程序。 我知道在垃圾收集过程中哪些对象没有被释放,但我无法确定引用它们的内容。 是否可以对JVM内部保存的对象图具有某种可见性? 否则可以找出哪些对象引用另一个对象?

无法为Java分配足够的堆空间

我们有一个运行良好一年的应用程序。 它是一个Web应用程序,在Windows Server 2003 Enterprise Edition Service Pack 2下的Microsoft Cluster下的Tomcat 5.5 + JDK 1.5下运行。服务器有11Gb的RAM(我知道它没用!),其中包含以下描述“物理地址扩展” :我不知道这意味着什么。 Tomcat服务配置了以下参数: -Xmx1024m -Xms128m 从上周开始,该服务不再需要启动并停止,并显示以下错误消息:“无法分配足够的堆空间”。 我们尝试了几个测试: java -Xmx1024m -version =>失败 java -Xmx758m -version =>失败 java -Xmx512m -version =>通过 因此,我们可以使用更少的内存来获得最大堆大小,但这不是一个可接受的解决方法,因为用户数量将在几个月内增加,我们需要将最大堆大小设置为1024Mb。 另外我不明白为什么它工作正常然后突然停止工作! 似乎操作系统现在无法分配连续内存或其他内容(页面文件大小,用户内存分配……) 由于Web应用程序在客户服务器上运行而我们无法访问它,因此很难知道某些内容是否发生了变化(操作系统补丁,配置等)。

根据JVM的内存粒度确定数组的最佳大小

为(例如)集合创建支持数组时,您并不真正关心所创建数组的确切大小,它只需要至少与您计算的一样大。 但是由于内存分配和VM的数组头,在某些情况下可以创建一个更大的arrays而不消耗更多的内存 – 对于Oracle 32位VM(至少这是互联网上的几个来源声称),内存粒度为8(意味着任何内存分配向上舍入到下一个8字节边界),并且数组头开销为12个字节。 这意味着在分配Object [2]时,它应该消耗20个字节(12 + 2 * 4),但由于粒度,它实际上需要24个字节。 可以为相同的内存成本创建一个Object [3],这意味着集合必须稍后调整其后备arrays的大小。 相同的原理可以应用于primitve数组,例如用于I / O缓冲区的byte [],字符串生成器中的char []等。 虽然这种优化不会产生明显的效果,但在最极端的情况下,调用静态方法来“优化”数组大小并不会太麻烦。 问题是,JDK中没有这样的“圆形arrays大小直至内存粒度”。 并且自己编写这样的方法需要确定VM的一些关键参数:内存粒度,数组头开销以及最终每种类型的大小(主要是引用的问题,因为它们的大小可能随架构和VM选项而变化)。 那么有没有一种方法来确定这些参数,或通过其他方式实现所需的“向上舍入”?

为什么要处理超出范围的java.awt.Window?

我在我们的应用程序中发现的一个内存泄漏是java.awt.Window.allWindows私有静态字段,它跟踪实例化的每个Window 。 我们创建,使用,然后忘记了对话框,期望这些对话框会消失并被垃圾收集。 这个私有字段无限期地将它们保留在范围内,直到在它们上调用dispose()方法。 根据定义,当他们超出范围时,我们不能这样做。 我不明白为什么这是这样设计的。 与垃圾收集的精神相反,当我完成Window对象时,必须明确地让系统知道。 显然我已经完成了它,因为它超出了范围。 我理解dispose()方法正在做什么:摆脱系统对等对象。 我确实理解这是在Java之外,你需要一些方法来做到这一点,并且Swing不应该只是失去对这些对象的跟踪,否则它会有内存泄漏。 但是,当我永远不再使用它时,通过永久保持对我的Window的引用来实现什么? 有人可以解释为什么这是必要的吗?

如何分析java中的内存碎片?

我们的服务器经历了几分钟的滞后。 可能它们是由“停止世界”垃圾收集引发的。 但是我们使用并发标记和扫描GC(-XX:+ UseConcMarkSweepG),所以,我认为,这些暂停是由旧一代的内存碎片触发的。 如何分析老一代的记忆碎片? 它有什么工具吗? 每小时就会发生一次陷阱。 大部分时间他们大约20秒,但有时 – 几分钟。

如果新的失败怎么办?

在C ++和C#中,当新的无法分配内存时,它会抛出exception。 我在Java中找不到有关new的行为的任何信息。 那么如果新的Java失败(内存不足)会发生什么?

Java“for”语句实现可防止垃圾回收

UPD 21.11.2017:该错误已在JDK中修复,请参阅Vicente Romero的评论 概要: 如果for语句用于任何Iterable实现,则集合将保留在堆内存中,直到当前作用域(方法,语句体)结束,即使您没有对集合的任何其他引用,也不会进行垃圾回收。应用程序需要分配新内存。 http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8175883 https://bugs.openjdk.java.net/browse/JDK-8175883 例子 : 如果我有下一个代码,它会分配一个包含随机内容的大字符串列表: import java.util.ArrayList; public class IteratorAndGc { // number of strings and the size of every string static final int N = 7500; public static void main(String[] args) { System.gc(); gcInMethod(); System.gc(); showMemoryUsage(“GC after the method body”); ArrayList strings2 = generateLargeStringsArray(N); showMemoryUsage(“Third allocation outside the method […]

java PermGen空间是整个VM内存的一部分吗?

假设我用以下参数启动我的java VM: -Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512m 512m PermGen空间是否会添加到1024m内存中,还是它们的一部分 ? 或者换句话说,我的总内存消耗是1536米还是1024米? 在后一种情况下,这是否意味着应用程序只有512m用于PermGen空间以外的目的? 如果这个问题显示对PermGen空间缺乏了解,请告诉我。 😉

Java桌面应用程序的内存分析

我的应用程序加载大约的数据集。 每次85bm到100mb。 应用程序的内存限制设置为512mb,从理论上讲,这已经足够了。 但是,我发现,如果在应用程序的单次运行中,我打开并关闭数据集5次,则总内存消耗会稳定增加,直到出现内存不足错误: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 6882 bguiz 20 0 679m 206m 19m S 30 13.7 0:30.22 java 6882 bguiz 20 0 679m 259m 19m S 9 17.2 0:55.53 java 6882 bguiz 20 0 679m 301m 19m S 9 20.0 1:20.04 java 6882 bguiz 20 […]

如何从JVM获取堆和permgen的最大大小?

我试图以编程方式找出调用我的程序的JVM的最大permgen和最大堆大小,而不是当前可用的。 有没有办法做到这一点? 我熟悉Java Runtime对象中的方法,但不清楚它们真正提供的是什么。 或者,有没有办法向Eclipse询问为这两个分配了多少?