You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java堆内存溢出问题排查:三元组求和代码报错

Fixing OutOfMemoryError in Your Triplet Sum Code

Hey there! Let's figure out why your triplet-finding code is throwing that OutOfMemoryError: Java heap space—even after you've tweaked the heap sizes in IntelliJ and Eclipse. Chances are, this isn't just a memory allocation issue—it's a problem with your algorithm's logic that's generating way more data than your JVM can handle. Let's break down the common culprits and fix them.

Common Causes & Solutions

1. Redundant Triplets from Duplicate Elements

If you're not handling duplicate values in your input array, you're probably generating hundreds (or thousands) of identical triplet lists. Each new list eats up memory, and before you know it, the heap is full.

Fix: Start by sorting your input array. This makes it easy to skip over duplicate elements during traversal, so you don't waste memory storing identical triplets.

2. Inefficient Brute-Force Enumeration

If you're using a naive triple nested loop to check every possible triplet, you're not just wasting time (O(n³) time complexity)—you're also creating tons of unnecessary intermediate lists. Even if most of them don't match your target sum, they still hang around in memory until the GC can clean them up.

Fix: Use the two-pointer technique after sorting the array. This cuts the time complexity down to O(n²) and drastically reduces the number of lists you create (only storing valid triplets).

3. Unintended Memory Leaks

Double-check if you're holding onto references to temporary lists or collections that you don't need anymore. For example, a global list that keeps accumulating data across loops, or local variables that aren't being properly discarded by the garbage collector.

Fix: Avoid global collections unless absolutely necessary, and clear out temporary lists once you're done with them.

Optimized Code Example

Here's a revised version of your code using the two-pointer approach, which fixes the memory issue by avoiding redundant triplets and unnecessary list creation:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TripletSumFinder {
    public static List<List<Integer>> findTriplets(int[] nums, int target) {
        List<List<Integer>> validTriplets = new ArrayList<>();
        
        // Edge case: Not enough elements to form a triplet
        if (nums == null || nums.length < 3) {
            return validTriplets;
        }
        
        Arrays.sort(nums); // Sort to enable duplicate skipping and two-pointer logic
        
        for (int i = 0; i < nums.length - 2; i++) {
            // Skip duplicate starting elements to avoid redundant triplets
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            
            int leftPointer = i + 1;
            int rightPointer = nums.length - 1;
            
            while (leftPointer < rightPointer) {
                int currentSum = nums[i] + nums[leftPointer] + nums[rightPointer];
                
                if (currentSum == target) {
                    // Only create a list when we find a valid triplet
                    validTriplets.add(Arrays.asList(nums[i], nums[leftPointer], nums[rightPointer]));
                    
                    // Skip duplicates on the left
                    while (leftPointer < rightPointer && nums[leftPointer] == nums[leftPointer + 1]) {
                        leftPointer++;
                    }
                    // Skip duplicates on the right
                    while (leftPointer < rightPointer && nums[rightPointer] == nums[rightPointer - 1]) {
                        rightPointer--;
                    }
                    
                    // Move pointers to check next possible pairs
                    leftPointer++;
                    rightPointer--;
                } else if (currentSum < target) {
                    leftPointer++; // Need a larger sum, move left pointer right
                } else {
                    rightPointer--; // Need a smaller sum, move right pointer left
                }
            }
        }
        
        return validTriplets;
    }

    public static void main(String[] args) {
        int[] sampleNums = {-1, 0, 1, 2, -1, -4};
        int targetSum = 0;
        
        List<List<Integer>> result = findTriplets(sampleNums, targetSum);
        for (List<Integer> triplet : result) {
            System.out.println(triplet);
        }
    }
}

Why This Works

  • Sorting: Eliminates duplicate triplets by letting us skip over identical elements quickly.
  • Two-Pointer Technique: Reduces the number of iterations from O(n³) to O(n²), which means way fewer intermediate objects cluttering up memory.
  • Selective List Creation: We only create a new list when we find a valid triplet, instead of generating lists for every possible combination.

Remember: If adjusting heap size doesn't fix the issue, the problem is almost always with your algorithm's efficiency, not the JVM's memory limits. Optimizing the logic will be the real solution here.

内容的提问来源于stack exchange,提问作者SuKhe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:13:03