Memory space manipulating in Java(Section four:Problems Resolving - part four)

本文详细探讨了Java堆中出现碎片化的现象及其原因,并提供了诊断和解决这一问题的方法。介绍了固定对象和中毒对象的概念,以及它们如何导致内存无法进行压缩整理,最终影响大对象分配。此外还提供了一些具体的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4. Fragmentation

4-1. Phenomenon

 Even there are enough space to be allocated, JVM got down with an OutOfMemory Error without generating a core file.

  As it may also depend on usage of your application or the system, the problem does not always can be reappeared.

  So what does the word Fragmentation means to your Java Heap? Concretely, it indicates that there are too many pinned/dosed objects exist in Java Heap, which can not be target of Compaction Action and would sprinkle about the heap in fragments. In such a condition, the trying to allocate space for a big object will end in failure.

  (Fragmentation issues are often also exacerbated due to frequent object allocations of large sizes, e.g. exceeding 1 MB).

  • Pinned Objects: are those that cannot be moved during heap compaction because of JNI (Java Native Interface) access to these objects. Also known as Un-Movable Object, which can not be moved out from memory by GC, due to they are referred by program languages (other than Java) via JNI.
  • Dosed Objects: Dosed Objects are those that cannot be moved during heap compaction due to references from the thread stacks directly. Normally, they would used as root objects to be scanning to identify all the reachable objects on Mark Phase of GC.

 

4-2. Handling

  Below is a simple approach to solve problems caused by fragmentation.

         

  1. Run your java application with a JVM argument –Xverbose:gc which will enable the output of information about GC activities.

    As an option, you can also set a JVM argument as follows to run your JVM:

-Dibm.dg.trc.print=st_verify (gives the number of pinned and dosed objects)

-Dibm.dg.trc.print=st_compact_verbose (lists the pinned and dosed objects)

This would enable the JVM to output information of pinned/dosed objects in GC activities in the following ways:

<GC(VFY-SUM): pinned=6696(classes=6472/freeclasses=0) dosed=2231

movable=622699 free=644085>

<GC(VFY-SUM): freeblocks: max=1543520 ave=139 (90010352/644085)>

<GC(VFYAC-SUM): freeblocks: max=2647896 ave=98024 (89986240/918)>

Notice that by default information outlined above would be outputted in the section of <GC> in your verbose:gc.

  2. When you see (from verbosegc) that the Java heap has a lot of free space, but the allocation request still fails, it usually points to a fragmented heap.

Here I will give an example to show you how the output of GC activity would be when a fragmentation was caused.

<AF[151]: Allocation Failure. need 33554448 bytes, 61085 ms since last AF>

------------------ (omission)

<GC(153): freed 37680 bytes, 75% free (404986096/536803840), in 2213 ms>

------------------ (omission)

<AF[151]: managing allocation failure, action=6 (404986096/536803840)>

<AF[151]: totally out of heap space>

    You should have noticed in where the problem be caused by seeing the above data.

    1) An AF happened due to the requirement for 33MB cannot be met in this case.

    2) Then a GC activity was invoked and 404MB in the heap become available.

    3) However, the AF still ends up with a failure and finally an out of heap space message was being outputted.

  3. If you have started your JVM with setting the argument -Dibm.dg.trc.print which I have introduced in step 1, check the number of pinned/dosed objects with the outputted information of the latest GC activities, a high number of which indicates a fragmented heap.

  4. There do have several ways for us to solve such a problem.

    Note that the following suggestions might not help avoid fragmentation in all cases.

  • Start with a small heap. Set -Xms far lower than -Xmx. It might be appropriate to allow -Xms to default, because the default is a low value.
  • Increase the maximum heap size, -Xmx.
  • If the application uses JNI, make sure JNI references are properly cleared. All objects being referenced by JNI are pinned and not moved during compaction, contributing significantly to heap fragmentation.  
<think>我们正在处理一个dpkg错误:`dpkg -i error: needs at least one package archive file argument` 这个错误通常发生在使用`dpkg -i`命令时,没有指定任何.deb文件作为参数。也就是说,用户可能忘记了提供要安装的软件包的文件名,或者提供的路径不正确。 根据引用[2]中提到的dpkg命令用法: dpkg -i 手动安装软件包 正确的用法是:`dpkg -i <package.deb>`,其中`<package.deb>`是.deb包的文件路径。 因此,解决方法是确保在`dpkg -i`后面提供至少一个.deb包的文件路径。 步骤: 1. 确认你已经下载了要安装的.deb文件,或者知道该文件的位置。 2. 在终端中,切换到.deb文件所在的目录,或者使用文件的绝对路径。 3. 运行命令:`sudo dpkg -i /path/to/package.deb` 如果遇到依赖问题,可以按照引用[2]和引用[3]中的建议,运行`sudo apt-get -f install`来解决依赖。 示例: 假设你下载了package.deb并放在Downloads目录下,那么可以这样安装: sudo dpkg -i ~/Downloads/package.deb 如果安装过程中出现依赖问题,则运行: sudo apt-get -f install 注意:如果.deb文件不在当前目录,必须提供完整路径或相对路径。 另外,如果用户试图安装多个包,可以同时列出多个.deb文件: sudo dpkg -i package1.deb package2.deb 但是,如果用户没有提供任何.deb文件,就会出现上述错误。 因此,请检查命令是否包含了.deb文件参数。 如果用户不记得下载的包在哪里,可以使用`find`命令查找: find ~ -name "*.deb" 或者使用图形界面在文件管理器中找到.deb文件,然后在终端中进入该目录执行安装。 总结:错误的原因是命令中缺少.deb文件参数,补充正确的文件路径即可。 相关问题: 1. 如何解决dpkg安装过程中的依赖问题? 2. 如何下载特定版本的.deb包? 3. 如何修复因dpkg安装中断导致的损坏包状态? 4. 如何卸载通过dpkg安装的软件包? 5. 如何查看已安装的.deb包的信息? 注意:在回答中,我们参考了引用[2]和[3]中关于dpkg和apt-get的使用方法。</think>### 解决 `dpkg -i` 错误:`needs at least one package archive file argument` 此错误表示 `dpkg -i` 命令**缺少有效的 .deb 安装包路径**。以下是完整解决方案: --- #### 1. **检查命令格式(核心问题)** ```bash # 错误示例(缺少文件路径): sudo dpkg -i # 正确格式: sudo dpkg -i /path/to/package.deb # 必须指定.deb文件路径[^2] ``` --- #### 2. **确认 .deb 文件存在** ```bash # 查找下载的 .deb 文件(默认在 /var/cache/apt/archives/) ls /var/cache/apt/archives/*.deb # 引用[3]中的关键路径 # 或手动下载包(以 Python 包为例): sudo apt download python-rospkg-modules # 下载到当前目录 sudo dpkg -i ./python-rospkg-modules*.deb # 安装下载的包 ``` --- #### 3. **修复依赖问题(常见后续错误)** 安装后若提示依赖错误,立即执行: ```bash sudo apt-get -f install # 自动修复依赖[^2][^3] ``` --- #### 4. **完整操作流程** ```bash # 步骤 1:下载包(若缺失) sudo apt download <package-name> # 步骤 2:安装包(指定完整路径) sudo dpkg -i /path/to/<package-name>*.deb # 步骤 3:修复依赖 sudo apt-get -f install # 步骤 4:验证安装 dpkg -l | grep -i <package-name> # 检查是否安装成功[^2] ``` --- #### 5. **特殊场景处理** - **空间不足问题**(引用[3]的警告): ```bash df -h /boot # 检查/boot分区空间 sudo apt autoremove --purge # 清理旧内核 ``` - **强制覆盖安装**(谨慎使用): ```bash sudo dpkg -i --force-overwrite /path/to/package.deb # 引用[3]方案 ``` --- ### 关键注意事项 1. 所有 `dpkg -i` 操作必须提供**完整的 .deb 文件路径** 2. 优先通过 `apt download` 获取合法安装包 3. 出现依赖问题时**立即执行 `apt-get -f install`** 4. 避免直接复制网页命令,需替换实际包名和路径 --- ### 相关问题 1. 如何修复 `dpkg: error processing package` 的依赖冲突? 2. `apt` 和 `dpkg` 命令在软件管理中的核心区别是什么? 3. 如何安全清理 `/boot` 分区空间不足导致的安装失败? 4. 下载的 .deb 包签名验证失败该如何处理? 5. 如何从源代码编译生成自定义 .deb 安装包? > 提示:使用 `man dpkg` 查看完整文档,或通过 `dpkg --help` 获取实时帮助[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值