Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix memory leak in liblinear - #34256

Merged
ogrisel merged 3 commits into
scikit-learn:mainfrom
jakevdp:fix-liblinear
Jun 12, 2026
Merged

Fix memory leak in liblinear#34256
ogrisel merged 3 commits into
scikit-learn:mainfrom
jakevdp:fix-liblinear

Conversation

@jakevdp

@jakevdp jakevdp commented Jun 11, 2026

Copy link
Copy Markdown
Member

There is a memory leak in LinearSVR, as demonstrated by this snippet (run on sklearn v1.9.0, but the issue predates this):

import os
import psutil
import numpy as np
from sklearn.svm import LinearSVR

def get_memory_usage():
    process = psutil.Process(os.getpid())
    return process.memory_info().rss / (1024 * 1024)

X = np.random.randn(1000, 10)
y = X.sum(axis=1)

for i in range(10001):
    if i % 2000 == 0:
        print(f"Iteration {i:5d}: Memory = {get_memory_usage():6.2f} MB")
    LinearSVR(max_iter=10).fit(X, y)

Output:

Iteration     0: Memory = 244.92 MB
Iteration  2000: Memory = 291.26 MB
Iteration  4000: Memory = 337.13 MB
Iteration  6000: Memory = 383.00 MB
Iteration  8000: Memory = 428.87 MB
Iteration 10000: Memory = 474.74 MB

Running under MSAN identified that the problem comes from memory allocated here:

*newprob = *prob;
newprob->l = l;
newprob->x = Malloc(feature_node*,l);
newprob->y = Malloc(double,l);
newprob->W = Malloc(double,l);

via this line:

remove_zero_weight(&newprob, prob);

but the memory is only freed in the else branch later in the function:

free(newprob.x);
free(newprob.y);
free(newprob.W);

The fix is straightforward: move these free lines outside the else branch, so that they're executed unconditionally.

AI usage disclosure

I used AI to research and understand the issue, but wrote the code in this PR manually.

@thomasjpfan thomasjpfan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codewise, I think this is a valid fix to a leak.

@ogrisel

ogrisel commented Jun 12, 2026

Copy link
Copy Markdown
Member

I confirm this fixes the leak from the reproducer on my box as well and the diff LGTM as well.

Let me add a changelog entry.

@ogrisel ogrisel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jakevdp!

@ogrisel
ogrisel enabled auto-merge (squash) June 12, 2026 09:44
@ogrisel
ogrisel merged commit 98113d6 into scikit-learn:main Jun 12, 2026
36 checks passed
@jakevdp
jakevdp deleted the fix-liblinear branch June 12, 2026 14:57
@lorentzenchr

Copy link
Copy Markdown
Member

@jakevdp This fix is very welcome. May I ask how the bug was discovered? Was it on a particular use case?

@jakevdp

jakevdp commented Jun 13, 2026

Copy link
Copy Markdown
Member Author

I was looking for the root cause of an unrelated memory leak outside scikit-learn, in code that uses scikit-learn, and the memory sanitizer caught this issue. It wasn’t the root cause of the issue I was debugging, but I figured I’d send a fix

@Fazel94

Fazel94 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

@jakevdp I think you PR aslo closes this issue #34029 is it correct?

prady0t pushed a commit to prady0t/scikit-learn that referenced this pull request Sep 2, 2026
@jeremiedbb jeremiedbb mentioned this pull request Sep 8, 2026
14 tasks
jeremiedbb pushed a commit that referenced this pull request Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants