JAVA 메모리 넘 침 사례 집계
프로그래머 로 서 많 든 적 든 메모리 가 넘 치 는 장면 을 만 날 수 있 습 니 다.만약 당신 이 아직 만 나 지 못 했다 면,당신 이 일 하 는 연한 이 비교적 짧 을 수도 있 고,아니면 당신 은 근본적으로 가짜 프로그래머 일 수도 있 습 니 다!하하,농담 입 니 다.오늘 우 리 는 자바 코드 의 방식 으로 몇 가지 전형 적 인 메모리 넘 침 사례 를 열거 할 것 입 니 다.여러분 들 이 일상적인 업무 에서 이러한 low 수준의 코드 를 쓰 는 것 을 최대한 피하 시기 바 랍 니 다.
주 클래스 구조 정의
우선,우 리 는 BlowUpJVM 이라는 클래스 를 만 들 었 고 그 후에 모든 사례 실험 은 이 클래스 를 바탕 으로 진행 되 었 다.아래 와 같다.
public class BlowUpJVM {
}
스 택 깊이 넘 침
public static void testStackOverFlow(){
BlowUpJVM.testStackOverFlow();
}
스 택 이 계속 재 귀 되 고 처리 되 지 않 아서 가상 컴퓨터 스 택 이 계속 깊이 들 어가 고 스 택 의 깊이 가 이렇게 넘 쳤 습 니 다.영구 메모리 넘 침
public static void testPergemOutOfMemory1(){
//
List<String> list = new ArrayList<String>();
while(true){
list.add(UUID.randomUUID().toString().intern());
}
}
String 상수 탱크 를 가득 채 우려 고 했 는데 실패 할 줄 은 몰 랐 습 니 다.JDK 1.7 이후 상수 탱크 를 더미 에 넣 어도 쓰레기 수 거 를 할 수 있 게 되 었 습 니 다.그리고 다른 방식 으로 cglib 를 사용 하여 Class 로 오래된 연 대 를 가득 채 웁 니 다.
public static void testPergemOutOfMemory2(){
try {
while (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOM.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
return proxy.invokeSuper(obj, args);
}
});
enhancer.create();
}
}
catch (Exception e){
e.printStackTrace();
}
}
가상 컴퓨터 가 성공 적 으로 메모리 가 넘 쳤 습 니 다.그럼 JDK 동적 에이전트 가 만 든 클래스 가 넘 칠 수 있 습 니까?
public static void testPergemOutOfMemory3(){
while(true){
final OOM oom = new OOM();
Proxy.newProxyInstance(oom.getClass().getClassLoader(), oom.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(oom, args);
return result;
}
});
}
}
사실 에 따 르 면 JDK 동적 에이전트 열등생 의 클래스 는 메모리 가 넘 치지 않 습 니 다.그 이 유 는 JDK 동적 에이전트 가 발생 하 는 클래스 정 보 는 영구적 인 세대 에 넣 지 않 고 쌓 여 있 기 때 문 입 니 다.로 컬 방법 스 택 넘 침
public static void testNativeMethodOutOfMemory(){
int j = 0;
while(true){
Printer.println(j++);
ExecutorService executors = Executors.newFixedThreadPool(50);
int i=0;
while(i++<10){
executors.submit(new Runnable() {
public void run() {
}
});
}
}
}
이 원 리 는 스 레 드 탱크 를 계속 만 드 는 것 입 니 다.모든 스 레 드 탱크 는 10 개의 스 레 드 를 만 듭 니 다.이 스 레 드 탱크 는 모두 로 컬 방법 구역 에 있 습 니 다.오 랜 시간 이 지나 면 로 컬 방법 구역 이 넘 칩 니 다.JVM 스 택 메모리 넘 침
public static void testStackOutOfMemory(){
while (true) {
Thread thread = new Thread(new Runnable() {
public void run() {
while(true){
}
}
});
thread.start();
}
}
스 레 드 생 성 은 JVM 스 택 에서 직접 생 성 됩 니 다.그러나 이 예 에서 메모리 가 넘 치 는 것 을 보지 못 했 습 니 다.호스트 가 먼저 끊 었 습 니 다.JVM 이 끊 은 것 이 아니 라 정말 호스트 가 끊 었 습 니 다.mac 에서 든 windows 에서 든 모두 끊 었 습 니 다.따뜻 한 힌트,이거 진짜 죽 어.
쌓다
public static void testOutOfHeapMemory(){
List<StringBuffer> list = new ArrayList<StringBuffer>();
while(true){
StringBuffer B = new StringBuffer();
for(int i = 0 ; i < 10000 ; i++){
B.append(i);
}
list.add(B);
}
}
쌓 아 올 린 StringBuffer 대상 을 계속 끼 워 넣 으 면 바로 넘 칩 니 다.테스트 사례 전체 코드
public class BlowUpJVM {
//
public static void testStackOverFlow(){
BlowUpJVM.testStackOverFlow();
}
//
public static void testPergemOutOfMemory1(){
//
List<String> list = new ArrayList<String>();
while(true){
list.add(UUID.randomUUID().toString().intern());
}
}
//
public static void testPergemOutOfMemory2(){
try {
while (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOM.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
return proxy.invokeSuper(obj, args);
}
});
enhancer.create();
}
}
catch (Exception e){
e.printStackTrace();
}
}
//
public static void testPergemOutOfMemory3(){
while(true){
final OOM oom = new OOM();
Proxy.newProxyInstance(oom.getClass().getClassLoader(), oom.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(oom, args);
return result;
}
});
}
}
//
public static void testNativeMethodOutOfMemory(){
int j = 0;
while(true){
Printer.println(j++);
ExecutorService executors = Executors.newFixedThreadPool(50);
int i=0;
while(i++<10){
executors.submit(new Runnable() {
public void run() {
}
});
}
}
}
//JVM
public static void testStackOutOfMemory(){
while (true) {
Thread thread = new Thread(new Runnable() {
public void run() {
while(true){
}
}
});
thread.start();
}
}
//
public static void testOutOfHeapMemory(){
List<StringBuffer> list = new ArrayList<StringBuffer>();
while(true){
StringBuffer B = new StringBuffer();
for(int i = 0 ; i < 10000 ; i++){
B.append(i);
}
list.add(B);
}
}
}
마지막 으로 병행 프로 그래 밍 에 습득 해 야 할 핵심 기능 지식 도 를 동봉 합 니 다.여러분 이 병행 프로 그래 밍 을 배 울 때 시행 착 오 를 적 게 걷 기 를 바 랍 니 다.이상 은 JAVA 메모리 넘 침 사례 를 모 은 상세 한 내용 입 니 다.JAVA 메모리 넘 침 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 해 주 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JAVA 객체 작성 및 제거 방법정적 공장 방법 정적 공장 방법의 장점 를 반환할 수 있습니다. 정적 공장 방법의 단점 류 공유되거나 보호된 구조기를 포함하지 않으면 이불류화할 수 없음 여러 개의 구조기 파라미터를 만났을 때 구축기를 고려해야 한다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.