[Apache] FATAL: emalloc(): Unable to allocate 792474677 bytes [Résolu]

Messages postés
445
Date d'inscription
lundi 17 février 2003
Dernière intervention
22 mars 2007
- - Dernière réponse :  RobertDeNiroZ - 9 sept. 2010 à 15:18
Bonjour à tous,
Je développe un site en php d'une dizaine de pages. Il tourne sous Apache2+php5 sur w2k. La plupart du temps tout fonctionne bien, mais de temps en temps, en ajoutant certaines instructions php (qui semblent vraiment anodines), Apache plante en affichant une fenêtre
Application popup : Apache.exe - Erreur d'application : L'instruction à "0x00837ca8" emploie l'adresse mémoire "0x05f71000". La mémoire ne peut pas être "read".

Cliquez sur OK pour terminer le programme.

Pas très explicite ! pas d'erreur php...

Alors je triture le code php pour ne pas utiliser telle ou telle syntaxe, et j'arrive à contourner comme ça le problème. Mais dès que j'implémente une nouvelle fonctionnalité, je retombe là-dessus.

Par exemple, tout fonctionnait bien, et j'ai ajouté ceci :
« while($ligneResultat=odbc_fetch_array($res)) { echo 'test'; }»
et maintenant ça plante ! pourtant le résultat est valide.

Dans le log d'erreur d'apache, il y a la ligne :
FATAL: emalloc(): Unable to allocate 892350769 bytes

Si quelqu'un a une idée, merci de m'aider...

Arn;o)
Afficher la suite 

Votre réponse

20/28 réponses

Meilleure réponse
Messages postés
1406
Date d'inscription
mercredi 17 août 2005
Dernière intervention
28 août 2007
5
3
Merci
Salut,



Dis moi ... T'es dans un plan galère là !?!

Voyon voâr !



<hr size="2" width="100%">memory_limit = 8M ; Maximum amount of memory a script may consume (8MB)
+

le processus Apache ne prend jamais plus de 7 ou 8 Mo

=

Le php.ini sert bien à quelque chose. C'est pas apache qui demande 2 Go de RAM

ET

Ca pourrait être la raison de l'erreur, "Apache :Allouer 2 Go !!! T'es pas dingue... Moi j'me casse!"

Donc il n'y a pas d'erreur dans ton script... (ce qui n'arrange pas l'affaire)

<hr size="2" width="100%">J'aurai une piste de réflexion : l'erreur provient de ta requète... Donc du code SQL, c'est là que serait la "boucle infinie".



Je m'explique :

Ta base de données, et en particulier son analyseur de SQL, est un
process indépendant d'Apache. Donc qui ce fout roal de php.ini.

Si tu fais une requète de taré genre

SELECT *

FROM tablePouet as t1, tablePouet as t2

WHERE t1.id != t2.id

La tu auras tout les croisements possible des champs de la table. Soit
une table de taillle !N si tablePouet contient N champs. Truc ouf koi
!!!



Tu me vois venir ?



Bon... ODBC il s'en fout lui... Il n'a pas de limite d'allocation
configurée (si ce n'est la limite autorisée par windows). Donc il en
pose un peu partout... Bref il s'arrange et on s'en fout de comment.
Mais il renvoit un lien vers le resultat. "Voici votre numéro de compte
client à rapeller lors de toutee communication ;)"



Mais quand tu demande à Apache de récupérer les données pour les
parser, ligne par ligne. Il demande à ODBC "fille moi le paquet et je
m'arrange avec". ODBC répond : "pas de problème ça fait 2Go". La suite
tu la connais.



Voilà pourquoi ça plante quand tu fait odbc_fetch_array()



Donc révise ta SQL....

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 121 internautes nous ont dit merci ce mois-ci

Commenter la réponse de J_G
Messages postés
2368
Date d'inscription
mercredi 13 octobre 2004
Dernière intervention
18 avril 2015
4
3
Merci
J'ai trouvé ca sur Google :



"

I have got a "solution" by finding many newsgroups and websites !! And
now I want to share with everyone who has encounter this problem.

If you have created a table in SQLServer has a data type "ntext" then
this problem (Fatal: emalloc() : unable to ....) will occur, please do
not use this data type.


"

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 121 internautes nous ont dit merci ce mois-ci

Commenter la réponse de FhX
Messages postés
1406
Date d'inscription
mercredi 17 août 2005
Dernière intervention
28 août 2007
5
3
Merci
Bingo !!!!!



Bravo Fhx!

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 121 internautes nous ont dit merci ce mois-ci

Commenter la réponse de J_G
Messages postés
10918
Date d'inscription
lundi 24 février 2003
Dernière intervention
2 mars 2010
32
3
Merci
Ahhh...SQLServer...puisque vous vous dites sur quoi vous bossez...moi
en ce moment, c'est le développement d'un SAE (système d'aide à
l'exploitation) sur les réseaux de transport, avec SQLServer, XMLRAD
2005 et Delphi (je suis sur la partie DB et DBGUI -gui => d'où
XMLRAD et delphi... ).

Ben je préfère mysql lol. Même en v3.x...les sous requêtes c'est bien, mais c'est lent, et c'est pas toujours super clair.



En tous cas, FhX t'as en effet peut-être donné une bonne piste :
vérifie tes types de champs...et ne mets que des "standards" SQL Ansi,
si possible.

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 121 internautes nous ont dit merci ce mois-ci

Commenter la réponse de malalam
Messages postés
1406
Date d'inscription
mercredi 17 août 2005
Dernière intervention
28 août 2007
5
0
Merci
FATAL: emalloc(): Unable to allocate 892350769 bytes !!!!!!!!!!!!!!!



!!! Oooouach, ça arrache !!!



Une simple formule mathématique va t'expliquer le problème :


892 350 769 bytes / (2^20) = 851,01201 Mo



Es-tu sûr d'avoir l'espace nécessaire en RAM ?



Question optimisation :

Il faut savoir que foreach() duplique les tableaux, alors que each() non !

_fetch_array() te sort la concaténation de _fetch_assoc() et _fetch_row()
Commenter la réponse de J_G
Messages postés
9440
Date d'inscription
mardi 9 octobre 2001
Dernière intervention
13 avril 2007
12
0
Merci
Salut,



une boucle infinie ailleurs peut-être ? un virus sur ta machine ?

<hr size="2" width="100%"><li>Entraide, dépannage et vulgarisation informatique : Mon site de vulgarisation informatique</li>
Commenter la réponse de cs_Anthomicro
Messages postés
2368
Date d'inscription
mercredi 13 octobre 2004
Dernière intervention
18 avril 2015
4
0
Merci
mysql_fetch_array($query,MYSQL_ASSOC)<tt>



</tt>Et la, plus de problème :)<tt>

</tt>
Commenter la réponse de FhX
Messages postés
445
Date d'inscription
lundi 17 février 2003
Dernière intervention
22 mars 2007
1
0
Merci
Merci à tous pour vos idées.

Je vais vérifier toutes mes boucles, et optimiser mon code selon les suggestions de J_G. C'est vrai que j'utilise très souvent foreach(), je ne savais pas qu'il fallait éviter...

Ce qui m'étonne, c'est que si j'avais fait une boucle infine, il devrait normalement y avoir une erreur php de max_execution_time, non ? Voici ma config à ce sujet (dans php.ini, c'est celle par défaut !)

;;;;;;;;;;;;;;;;;;;
; Resource Limits ;
;;;;;;;;;;;;;;;;;;;
max_execution_time = 30 ; Maximum execution time of each script, in seconds
max_input_time = 60 ; Maximum amount of time each script may spend parsing request data
memory_limit = 8M ; Maximum amount of memory a script may consume (8MB)

A croire qu'Apache n'en tient pas compte ?

En tout cas, c'est clair une telle demande de mémoire n'est pas acceptable par la machine, et encore, je suis en mode test et je suis le seul visiteur ! Ce qui est bizarre c'est que dans le gestionnaire de processus de Windows, le processus Apache ne prend jamais plus de 7 ou 8 Mo...

Sinon, j'utilise les sessions, alors j'avais pensé que je mémorisais trop de chose dans mes sessions, mais les fichiers créés dans le répertoire temporaires ne dépassent pas les 170 Ko !
J'ai aussi essayé en revenant à Apache 1, même problème.

Je ne pense pas avoir de virus, j'ai un AV à jour (SophosAV) et je teste toute la machine tous les jours...

FhX, j'utilise une connexion odbc et pas mysql, alors la fonction est odbc_fetch_array()... les arguments ne sont pas les mêmes que mysql_fetch_array(). Merci qd même.
J_G, odbc_fetch_assoc() ça n'existe pas ;o)
En fait, même si j'utilise odbc_fetch_object() ça plante...
Commenter la réponse de arnal69130
Messages postés
445
Date d'inscription
lundi 17 février 2003
Dernière intervention
22 mars 2007
1
0
Merci
Je viens d'essayer avec odbc_fetch_row directement, et ça ne plante plus ! super, pourvu que ça dure ;o)
Merci encore à tous les 3.
A+
Arn;o)
Commenter la réponse de arnal69130
Messages postés
445
Date d'inscription
lundi 17 février 2003
Dernière intervention
22 mars 2007
1
0
Merci
:-s
En fait ça marche pas, je me suis emballé pour rien, désolé...
Commenter la réponse de arnal69130
Messages postés
445
Date d'inscription
lundi 17 février 2003
Dernière intervention
22 mars 2007
1
0
Merci
Le plus pénible pour trouver la source de l'erreur, c'est que
- si j'enlève le bout de code en question, ça marche
- si je le mets avec tout le reste du code, ça plante
- mais si je ne mets que ce bout de code (plus la connexion à la base), ça ne plante pas !

Voici un peu plus de code, si jamais ça vous inspire :
$_SESSION['connexion']=odbc_connect("blablabla","","") or die("Erreur de connexion".odbc_errormsg());
$req="SELECT blablabla FROM blablabla WHERE blablabla ";
$res=odbc_exec($_SESSION['connexion'],$req);
if (!empty($res)) {
$nbChamps=odbc_num_fields($res);
echo '
---
';
while(odbc_fetch_row($res)) {
for ($i=1; $i<=$nbChamps; $i++)
echo odbc_field_name($res,$i).'='.odbc_result($res,$i).'
';
}
odbc_free_result($res);
}
exit;

et toujours les mêmes logs pour Apache (mais la mémoire requise a augmenté !) :
[Thu Oct 06 10:38:12 2005] [notice] Parent: child process exited with status 3221225477 -- Restarting.
[Thu Oct 06 10:38:13 2005] [notice] Apache/2.0.54 (Win32) PHP/5.0.5 configured -- resuming normal operations
[Thu Oct 06 10:38:13 2005] [notice] Server built: Apr 16 2005 14:25:31
[Thu Oct 06 10:38:13 2005] [notice] Parent: Created child process 872
[Thu Oct 06 10:38:14 2005] [notice] Child 872: Child process is running
[Thu Oct 06 10:38:14 2005] [notice] Child 872: Acquired the start mutex.
[Thu Oct 06 10:38:14 2005] [notice] Child 872: Starting 250 worker threads.
FATAL: emalloc(): Unable to allocate 1920220171 bytes
[Thu Oct 06 10:38:18 2005] [notice] Parent: child process exited with status 3221225477 -- Restarting.
...

Je me penche sur les foreach...

Arn;o)
Commenter la réponse de arnal69130
Messages postés
10918
Date d'inscription
lundi 24 février 2003
Dernière intervention
2 mars 2010
32
0
Merci
De toutes évidences, il y a un truc qui bouffe BCP de ram, là... 1920220171 bytes, ça fait très très beaucoup...

Et si ça ne venait pas de ton script, mais de ton système ? Il y a
peut-être une tâche un peu bizarre qui tourne, et qui peut-être
interfère avec apache.
Commenter la réponse de malalam
Messages postés
445
Date d'inscription
lundi 17 février 2003
Dernière intervention
22 mars 2007
1
0
Merci
Alors là J_G, super ! ton explication est très claire et je suis vraiment content de pouvoir envisager une issue à ce problème. Honnêtement, je ne voyais pas bien vers où chercher, mais ton raisonnement est très logique.

J'utilise une base HyperFile, c'est la base de données livrée avec Windev, je n'ai pas le choix ! Et c'est vrai que j'ai déjà constaté plusieurs fois que c'est pas l'idéal comme système, car c'est une base dite "fichier", pas un sgbd ! Enfin bon, il faut que je fasse avec, alors je vais reprendre toutes mes grosses requêtes.
Cela dit, la requête en question ne retourne pas plus de 20-30 lignes et 22 colonnes.... Enfin en tout cas, je cherche dans cette direction.

Merci.

Malam, merci pour la suggestion. J'ai essayé en n'ayant que apache, iexplore et les trucs windows qui tournaient, mais ça plantait pareil...
Commenter la réponse de arnal69130
Messages postés
1406
Date d'inscription
mercredi 17 août 2005
Dernière intervention
28 août 2007
5
0
Merci
Hmmm...



Mauvaise nouvelles des étoiles !

"Cela dit, la requête en question ne retourne pas plus de 20-30 lignes et 22 colonnes"

Ca sent pas bon ça !!! J'ai peur de te faire bidouliler dans la mauvaise direction...



Cela dit: j'ai eu cette piste de réflexion car tu utilises ODBC ! Et
effectivement, les bases à wouinnedauze ne fonctionnent pas avec un
serveur résident, mais une API lancée à chaque fois que tu dois accéder
au fichier de la base.

La commande de lancemement de cette API dois certainement être
configurée dans le php.ini, ou faire partie des extentions php.
Peut-être un coup d'oeil dans ce coin te sauvera ta journée... (Là, je
parle sans regarder dans la doc)

Si tu y flaire un "bottle-neck", il existe des serveurs qui savent
accéder au bases type ADO et ODBC (peut-être même que IIS le fait !
Après, de là à demander à Apache et IIS de faire copain-copain... c'est
pas gagné !). Configure ton Apache pour faire des appels à ce serveur
plutôt que de lancer une API distincte!



Bonne chance, dis-moi si tu y arrive !



PS : Toutes les bases de données utilisent des fichiers !!! Ben oui, on
à rien inventé d'autre pour stocker des données sur un ordi quand y'a
plus de courant électrique ;)

PPS : Ne dis pas de mal de Windows sur ce forum !!! Où le modérateur-fou frappera encore ;)
Commenter la réponse de J_G
Messages postés
1406
Date d'inscription
mercredi 17 août 2005
Dernière intervention
28 août 2007
5
0
Merci
Tiens regarde !!! (et lis le passage que j'ai mis en rouge)

On dirait que ODBC et PHP... c'est une longue histoire :(



Hurles : http://fr.php.net/manual/fr/function.odbc-setoption.php

<hr size= "2" width="100%">

odbc_setoption


(PHP 3 >= 3.0.6, PHP 4, PHP 5)

odbc_setoption -- Modifie les paramètres ODBC


Description
bool odbc_setoption ( resource id, int function, int option, int param )


odbc_setoption() donne accès aux options
ODBC pour une connexion particulière ou un résultat de
requête. Elle a été écrite pour aider à
la résolution de problèmes liés aux pilotes ODBC
récalcitrants. Vous aurez sûrement à utiliser
odbc_setoption() si vous êtes un programmeur
ODBC et que vous comprenez les divers effets des options disponibles.
Vous aurez aussi besoin d'un bon manuel de référence pour
comprendre les options et leur usage. Différentes versions de
pilotes supportent différentes versions d'options.



Etant donné que les effets peuvent varier d'un pilote à
l'autre, l'utilisation de odbc_setoption() dans
des scripts voués à être livrés au public
est très fortement déconseillée. De plus, certaines
options ODBC ne sont pas disponibles car elles doivent être
fixées avant l'établissement de la connexion. Cependant,
si dans un cas bien spécifique, odbc_setoption()
vous permet d'utiliser PHP sans que votre patron ne vous pousse à
utiliser un produit commercial, alors cela n'a pas d'importance.



<var>id</var> est un identifiant de connexion, ou un identifiant
de résultat, pour lequel vous souhaitez modifier des options.
Pour SQLSetConnectOption(), c'est un identifiant de connexion.
Pour SQLSetStmtOption(), c'est un identifiant de résultat.



<var>function</var> est la fonction ODBC à utiliser.
La valeur doit être de 1 pour utiliser SQLSetConnectOption() et 2
pour SQLSetStmtOption().



Le paramètre <var>option</var> est l'option à
modifier.



Le paramètre <var>param</var> est la valeur de l'option
<var>option</var>.
Exemple 1. Exemple de modification d'option ODBC

<table bgcolor ="#e0e0e0" border="0" cellpadding="5">----,

<?php

// 1. L'option 102 de SQLSetConnectOption() est SQL_AUTOCOMMIT.

// 1 de SQL_AUTOCOMMIT est SQL_AUTOCOMMIT_ON.

//    Cet exemple a le m&#234;me effet que

//    odbc_autocommit($conn, true);

odbc_setoption($conn, 1, 102, 1);

// 2. Option 0 de SQLSetStmtOption() est SQL_QUERY_TIMEOUT.

//    Cet exemple fixe le d&#233;lai d'expiration &#224; 30 secondes.

$result = odbc_prepare($conn, $sql);

odbc_setoption($result, 2, 0, 30);

odbc_execute($result);

?>


</td>

</td></tr></tbody></table>
Commenter la réponse de J_G
Messages postés
445
Date d'inscription
lundi 17 février 2003
Dernière intervention
22 mars 2007
1
0
Merci
En fait j'ai rien contre Windows, je parle de Windev ! et encore, j'ai rien contre Windev non plus, c'est juste contre leur base de données, Hyperfile. Ce n'est pas un "programme" ou un "service" attendant des requêtes SQL, ce sont juste des fichiers textes (en gros). Enfin de toute façon, comme je le disais plus haut, je n'ai pas le choix, alors ça sert à rien de me plaindre, ça ne fera pas avancer le problème ;o)

Je vais regarder odbc_setoption de ce pas...

Merci encore

Arn;o)
Commenter la réponse de arnal69130
Messages postés
445
Date d'inscription
lundi 17 février 2003
Dernière intervention
22 mars 2007
1
0
Merci
[HS]
Le format de fichiers HyperFile est proprietaire et non ouvert. Il a les inconvenients suivants...

1- Format non reconnu par tous les autres logiciels
2- Probleme de fragmentation et d'incoherence d'index
3- Obligation de reindexation frequente (lie au pb 2)
4- Probleme d'utilisation en reseau avec bcp d'utilisateurs (lie au pb 2)
5- Pas un vrai SGBD
6- ODBC non conforme
http://membres.lycos.fr/windev/souh064.htm

/HS
Commenter la réponse de arnal69130
Messages postés
1406
Date d'inscription
mercredi 17 août 2005
Dernière intervention
28 août 2007
5
0
Merci
<HS type="text" name="commentaire superflue">

Et ben t'es pas dans la merde !

</HS>
Commenter la réponse de J_G
Messages postés
445
Date d'inscription
lundi 17 février 2003
Dernière intervention
22 mars 2007
1
0
Merci
En fait, ça fait près de 3 ans que je bosse sur PHP / Hyperfile via odbc, et il y a qd même de quoi avancer ;o) ...

Arn;o)
Commenter la réponse de arnal69130
Messages postés
1406
Date d'inscription
mercredi 17 août 2005
Dernière intervention
28 août 2007
5
0
Merci
Pour quelle entreprise ?

(Si ce n'est pas indiscret)



Moi je bosse avec une version 3.23 de MySQL

C-à-d. : PAS DE SOUS-REQUETES !!!!!!! C'est infernal :( :( :( :(

Alors ton ODBC mis-à-jour me ferait presque réver ;)



<maVie>

Ou alors je n'ai pas trouvé la bonne syntaxe pour MySQL 3.23.

Mais je ne trouve pas non-plus de doc pour cette version et la doc de
la version 5 te dit : "vas-y à la Jack ! Sous-requètes, imbriquées dans
le désordre... C'est bon c'est bon, si tu as mieux que la version 4.1"

Merci, sympas pour l'info !

</maVie>
Commenter la réponse de J_G

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.